Skip to content
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

Closed
prime2358 opened this issue Aug 22, 2023 · 8 comments
Closed

Comments

@prime2358
Copy link

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)

  • where option is an enum: STRONG, ANY
  • timeout is the timeout in millisecundum
  • result is a promise with true or false

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.

@twiss
Copy link
Member

twiss commented Aug 22, 2023

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.

@prime2358
Copy link
Author

As far as I understand, in the webauthn implementation of passkeys there is no attestation.
If Apple/Google/Microsoft think it is ok to have blind trust in the user agent, why is it a problem with my proposal?

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:
#350

with encryption/decryption too.

@twiss
Copy link
Member

twiss commented Aug 22, 2023

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)

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.

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.

You don't need a password manager for WebAuthn, the platform can implement the API directly.

@prime2358
Copy link
Author

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:
https://developer.apple.com/forums/thread/713195

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.

@prime2358
Copy link
Author

But again, it is another proposal that is about signing (350).
I do not care about webauthn. It is a very special web authentication solution.
I want biometrics support for web crypto operations, for decryption as well as signing.
It is just a coincidence that if I have biometrics access to support a sign operation, it might be a simple browser level alternative to platform/pass manager level passkeys.

@r-jo
Copy link

r-jo commented Aug 22, 2023

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:

  • passkey is on pass manager level on apple platforms
  • attestation is not needed, it is some baggage since "the spec was written with device-bound credentials in mind"
  • apple will always sync the passkey

"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."

@twiss
Copy link
Member

twiss commented Aug 22, 2023

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.

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).

I do not care about webauthn. It is a very special web authentication solution.

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.

@twiss twiss closed this as completed Aug 22, 2023
@prime2358
Copy link
Author

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 decryption 2nd factor:

  • the device is logged in with passwords or whatever
  • sensitive data is stored encrypted in case some malicious js can read indexed db
  • the person having the device can see this sensitive stuff ONLY if it provides biometrics/PIN, then you decrypt and show the data
    [you can encrypt data against js theft and show it to anybody that has the logged in device NOW, but biometrics would enhance security with a 2nd factor like leaving the device unattended, having no automatick lock, losing such device etc.]

one for authentication 2nd factor:

  • you have access token system and an ECDSA private key stored in browser for device authentication
  • since access tokens travel and may be stolen more easily then unextractable private keys, you have a system that refreshes access tokens by signign with private keys (you might need a very fresh access token to do sensitive stuff)
  • now, you might want to delete something on the server and all we can do now with web crypto is to make sure the browser/device makes this request but we cannot be sure if the account holder operates the device, it would be a second factor

A native app has access to yes/no biometrics, it obviously has use cases.
A web app should also have access and reason is this 2nd factor for web crypto operations.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants