-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enable device biometrics / PIN check to support web crypto operations #352
Comments
Hello 👋 To be perfectly honest, I think such an API is not a very good idea because it implies that the web application places blind trust in the user agent to verify the user, and also trusts the user not to change this code to do something else. So, it would be better to return some kind of attestation (in the success case) rather than just a boolean. Additionally, I think this functionality belongs in (and overlaps with the existing functionality of) WebAuthn, not Web Crypto. |
As far as I understand, in the webauthn implementation of passkeys there is no attestation. Why is it more secure to call navigator.credentials.get() from webauthn? All I get there is a proof that some kind of authenticator (pass manager on the device) has the private key and I blindly trust the user agent. Or is there some hidden security in the webauthn specs I do not understand? (possible) Still, why should a third party pass manager a better authenticator then the browser itself? It is a native app. I understand your feeling about webauthn but does that really cover what I want? I want that when using a web crypto function like signing or encryption/decryption, I get some ADDITIONAL security that the browser not only has an unextractable private key, but the device owner operates the browser. The user verification check is intented to be coupled to a web crypto operation. I really see no security benefit from webauthn but as said, it needs a pass manager which not every user has and which is a huge added complexity. With web crypto I can store the keys in the browser without needing a pass manager. But if we need coupling with functions for some security purposes, we could do something like: with encryption/decryption too. |
You do get an attestation from the private key, and you can check that it's the same key that registered earlier. So, you can check (for example) that the owner of the device that registered is the same as the one logging in.
You don't need a password manager for WebAuthn, the platform can implement the API directly. |
I think attestation is an added complexity that is beneficial for security keys (which is also coupled to webauthn). Apple killed attestation if I am not mistaken: If I use the webauthn API, the passkey will be in Apple Keychain or Google Password Manager, synced, or on Microsoft platform which I do not quite understand where and how and it is under construction. And I cannot use bioemtrics as extra before decrypting something with my unextractable key in the browser. I suggested biometrics access as support for all web crypto functions where it makes sense. Encrypting sensitive info like credit card data, storing in client browser and decrypting it only to the owner of the device is a use case. I already use ECDSA private keys in the browser when refreshing access tokens. Another super use case to also check biometrics (PIN, device unlock) before doing so, in some cases. Netflix keeps you logged in and you can see sensitive account data from each logged in device (netflix proposed this web crypto api and I am sure they use browser stored keys and not webauthn). Would not it be beneficial to require biometrics before deleting a device or the account or doing any sensitive stuff? Now you can do it from a logged in device. What is the harm or security problem to add biometrics before some of the actions too? A browser as a native app has access to biometrics. |
But again, it is another proposal that is about signing (350). |
I think it is the same on google platforms, but nice link from apple if I am not mistaken, garrett-davidson from Apple Passkeys says exactly what we say:
"Assuming you're using a version of Safari with passkeys, this is expected behavior. Attestation statements are intended to attest to the security properties of the device where the credential lives, as the spec was written with device-bound credentials in mind. In a world where the credential can sync to devices with different security properties, a one-shot attestation during registration can't provide any meaningful promises about all of the devices where the passkey can be used. There's ongoing work in the spec to try to improve this, but keep in mind that passkeys are replacements for passwords, and passwords don't have attestation either 🙂 There is a better way! There's a merged PR to the WebAuthn spec that will be included in the upcoming WebAuthn L3. It specifies two new "backup state" bits in the authenticatorData field: to indicate whether a credential "can be" backed up, and whether it "is" backed up. Passkeys on Apple platforms have already adopted this and always set both bits to true." |
To be perfectly honest, this threat model doesn't really make sense from a cryptographic perspective. You should first make sure that the public key you encrypt the sensitive data with belongs to the person you want to have the data, and only then encrypt it, rather than adding checks before decryption. Remember that the user can always get the data and keys from the memory or storage of the browser and decrypt it manually, bypassing such checks. Unextractable keys are meant to be a protection against the web application, not against the user (and in fact there's no requirement for them to be inaccessible by the user somehow).
When I said "WebAuthn" I meant the Web Authentication Working Group at the W3C, not the API as it currently exists today. If you have issues with the WebAuthn API, you should reach out to the WebAuthn WG. The Web Crypto API is really not the right place to add such functionality in my opinion, so I'll close this issue. |
I simply dont understand what you write, sorry. A native app can ask for biometrics and get a yes/no answer. My banking app asks for biometrics before showing my card data. I am already logged in, authenticated but what if I am not by my device? I think you really just cant get rid of the thinking that we want a full scale authentication solution. That is why you dont understand that no one wants to replicate webauthn. No, we just want the second factor: want a simple way to check biometrics before doing decryption or signing. I mentioned 2 use cases:
one for authentication 2nd factor:
A native app has access to yes/no biometrics, it obviously has use cases. Like an offline working pwa that provided sensitive data to the web app and does not want or can fully re-authenticate could ask for biometrics 2nd factor before decrypting and showing things in indexed db. It is encrypted against online js attacks but we want to decrypt and show this data only to the device owner. Even offline. No full scale authentication, no webauthn (which by the way works only online coupled to a pass manager based authentication. Same with device authentication. You have a system like netflix where you are logged in and if you delete something it surely checks not just access token but also private key in browser. No password needed. No passkeys used. You could just let the device delete some server stuff if you check in addition to the private key that the device owner operates the device. |
The first use case of web crypto, mentioned by the specs:
https://www.w3.org/TR/WebCryptoAPI/#multifactor-authentication
Now that webauthn has access (a web monopoly) to device biometrics / PIN checks, but it is implemented with passkeys that require pass managers to create, store (and that even sync) private keys, I think web crypto standard would be the right place to standardize a secure but more simple biometrics / PIN access like:
subtle.crypto.verifyUser(option, timeout = 100_000)
This would be like a second factor for any (!) crypto operation like signing challenges or encrypring / decrypting data.
In native apps you increasingly see biometrics check before revealing sensitive information like card numbers. This could be done in a web app by encrypting data and have an unextractable decryption key in indexed db, which we would only use to decrypt sensitive data if above call returns with true.
In addition, we could store an unextractable private key in the browser for signing authentication challenges from the server and now we could decide to do it silently (like refreshing an access token) or demanding a kind of user verification (like ANY for less sensitive, STRONG for more sensitive actions).
See: #350
Apple, Google, Microsoft platforms have different classification of "device unlock" security levels, it would be great to achieve a good definition of what is considered STRONG.
The text was updated successfully, but these errors were encountered: