SelfLender / react-native-biometrics

React Native module for iOS and Android biometrics
MIT License
653 stars 221 forks source link

Why verification still works if Face ID has been reset? #245

Open olegderecha opened 1 year ago

olegderecha commented 1 year ago

Happy path:

But when I go to the device Settings, reset Face ID, and create a new one (using my face or another person's), I can call rnBiometrics.createSignature and it will work again even technically it is another person's Face ID. Do I miss something?

xuanmai-agilityio commented 1 year ago

I'm wondering about the same issue. If the hacker/thief got the device and knew the passcode, they could change the FaceID or any biometric. After that, they will be able to log in with the new FaceID/biometric. That's a risk. Do we have any solution to detect 1 FaceID for the createSignature or when having FaceID, biometric change to delete private key in the keychain?

olegderecha commented 1 year ago

@xuanmai-agilityio , seems the biometrics is device-level protection and not user-level. It means, if the device is hacked (in reality is not a very big probability if secure codes are rather strong) or you are allowed to change your FaceID to your wife/relative - it means you are allowed to access the device and then as a result - all apps inside the device.

xuanmai-agilityio commented 1 year ago

@olegderecha Just had some research and seem found the solution to detect when FaceID reset/changes. Just need to update the value kSecAccessControlBiometryAny in the ReactNativeBiometrics.m with the kSecAccessControlBiometryCurrentSet value. It will only restrict the key to be accessed by the current biometric set at the moment we generate the key pair. So when FaceID is reset, the biometricKeysExist function will return false. I referred to these docs for the solution. Could you check and give confirmation from your side? https://developer.apple.com/documentation/security/secaccesscontrolcreateflags/ksecaccesscontrolbiometrycurrentset https://blog.nviso.eu/2021/04/06/a-closer-look-at-the-security-of-react-native-biometric-libraries/

minhnguyenvan95 commented 1 year ago

@olegderecha Just had some research and seem found the solution to detect when FaceID reset/changes. Just need to update the value kSecAccessControlBiometryAny in the ReactNativeBiometrics.m with the kSecAccessControlBiometryCurrentSet value. It will only restrict the key to be accessed by the current biometric set at the moment we generate the key pair. So when FaceID is reset, the biometricKeysExist function will return false. I referred to these docs for the solution. Could you check and give confirmation from your side? https://developer.apple.com/documentation/security/secaccesscontrolcreateflags/ksecaccesscontrolbiometrycurrentset https://blog.nviso.eu/2021/04/06/a-closer-look-at-the-security-of-react-native-biometric-libraries/

Hi @xuanmai-agilityio , I've follow your answer and It worked fine with ios, but with android no error code or exception is thrown ( BIOMETRIC_ERROR_NONE_ENROLLED ).

Do you have any ideas about this ?

xuanmai-agilityio commented 1 year ago

@minhnguyenvan95 It's just for iOS. On Android, we need to update to add one more option in the ReactNativeBiometrics.java on lines 103-104 in the createKeys method. The result should be like this:

.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build();

It will invalidate the old private key if having any biometric enrollment after the moment we register in our app. But we can not check with the biometricKeysExist function on Android, because it's just invalidated, not deleted. So I suggest we should check the biometric changes for both Android and iOS by using the createSignature function. It will fail on both platforms with different error messages, but at least we can handle them in one place. Hope this help! Cheers!

minhnguyenvan95 commented 1 year ago

@xuanmai-agilityio Thank you, biometricKeysExist return false for iOS and true for Android when biometric changed. So I will try your solution by using createSignature and will post the result here.

satheeshwaran commented 1 year ago

I checked createSignature after adding a new fingerprint on Android and I was getting a valid signature.

mloisotto commented 11 months ago

Any updates on this? I'm stuck in doing the same verification.

zungx commented 3 weeks ago

out the same issue. If the hacker/thief got the device and knew the passcode, they could change the FaceID or any biometric. After that, they will be able

Do you have any update on this one?

xuanmai-agilityio commented 3 weeks ago

out the same issue. If the hacker/thief got the device and knew the passcode, they could change the FaceID or any biometric. After that, they will be able

Do you have any update on this one?

Please refer to my comments above. In general, we would need to update a little bit in the native code and handle the error on both platforms when calling this function (createSignature)