New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 828567 link

Starred by 2 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 2
Type: Bug



Sign in to add a comment

navigator.credentials.get is not respecting `allowCredentials`

Reported by sra...@duosecurity.com, Apr 3 2018

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36

Steps to reproduce the problem:
1. Use a Yubikey and Github SoftU2F
2. Register a Yubikey credential with `navigator.credentials.create`
3. Start an auth ceremony with `navigator.credentials.get` and pass in the stored credential ID in `allowCredentials`
!4. Both the Yubikey and SoftU2F flash for an auth ceremony.

What is the expected behavior?
As per the spec I would expect only the Yubikey to be requested for an auth ceremony, but both/all authenticators are requested.

What went wrong?
What happens instead

- Both the yubikey and softu2f token request ceremonies
- The auth fails on the client if I perform the ceremony with the wrong authenticator

Did this work before? No 

Does this work in other browsers? N/A

Chrome version: 65.0.3325.181  Channel: stable
OS Version: OS X 10.13.3
Flash Version:
 
Labels: Needs-Triage-M65

Comment 2 by tkent@chromium.org, Apr 4 2018

Components: Blink>SecurityFeature>CredentialManagement
Cc: susan.boorgula@chromium.org
Labels: Triaged-ET TE-NeedsTriageFromHYD
sraman@ Thanks for the issue.

As this issue is related to Yubikey security key, this is not available at TE end to test the issue.

Hence adding TE-NeedsTriageFromHYD label and requesting someone from Inhouse team to look into this issue and help in further triaging.

Thanks..
Thanks for the response! Are you certain the issue is Yubikey specific? The same behavior occurs if I register the SoftU2F token and attempt to filter on it; the Yubikey flashes. 
Labels: Needs-Feedback
sraman@ i have an access to yubico smart key, could you please help us with sample html case and it expected behaviour  for further triage.

Thank You...
Hello! You can replicate the behavior on https://webauthn.bin.coffee/.

Quoting the expected behavior:

What is the expected behavior?
As per the spec I would expect only the Yubikey to be requested for an auth ceremony, but both/all authenticators are requested.

What went wrong?
What happens instead

- Both the yubikey and softu2f token request ceremonies
- The auth fails on the client if I perform the ceremony with the wrong authenticator


Project Member

Comment 7 by sheriffbot@chromium.org, Apr 5 2018

Cc: kkaluri@chromium.org
Labels: -Needs-Feedback
Thank you for providing more feedback. Adding the requester to the cc list.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -TE-NeedsTriageFromHYD TE-NeedsTriageHelp
Unable to triage this issue from TE-end, hence adding TE-NeedsTriageHelp label for further triage

Requesting SecurityFeature team to look into this issue.
Cc: engedy@chromium.org
Hi Balazs,

Is this something you could help with triaging?
Cc: agl@chromium.org arnarb@chromium.org
Components: -Blink>SecurityFeature>CredentialManagement Blink>WebAuthentication
Status: Available (was: Unconfirmed)
The rationale for this behavior is that if we didn't wink any and all connected authenticators, the user might mistakenly believe that those not flashing are broken in some way. (This can be especially frustrating if you have a single (unregistered) authenticator connected and that does not start flashing.)

Furthermore, we cannot fail the WebAuthn request immediately if no registered authenticators are connected either, because the correct authenticator might be hot-plugged later. There are also privacy considerations at play (https://www.w3.org/TR/webauthn/#sec-assertion-privacy).

If the user touches the wrong authenticator, the relying party is informed of this, i.e. the promise will reject with an InvalidState error. The current error description is wrong ("Attempting to register an already-registered key."), which is a bug, and is being fixed by crrev.com/c/1006482.

So at the end of the day, the only party here that is in a position to handle this is the web site itself, which is supposed to inform the user that the key was not yet registered.


Comment 11 by agl@google.com, Apr 12 2018

(This is also the behaviour that we've always had with the U2F extension.)
My reading of the spec is that not that the request should fail instantly, but only authenticators described in `allowCredentials` are "winked", as they are filtered beforehand.



https://w3c.github.io/webauthn/#GetAssn-DetermineRpId
```
If options.allowCredentials

is not empty
Let allowCredentialDescriptorList be a new list.

Execute a platform-specific procedure to determine which, if any, public key credentials described by options.allowCredentials are bound to this authenticator, by matching with rpId, options.allowCredentials.id, and options.allowCredentials.type. Set allowCredentialDescriptorList to this filtered list."

...

if distinctTransports

is not empty
The client selects one transport value from distinctTransports, possibly incorporating local configuration knowledge of the appropriate transport to use with authenticator in making its selection.

Then, using transport, invoke the authenticatorGetAssertion operation on authenticator, with rpId, clientDataHash, allowCredentialDescriptorList, userPresence, userVerification, and authenticatorExtensions as parameters.
```


Yes, I can imagine that for some types of (built-in) platform authenticators we could do some filtering there. However, for U2F authenticators, which are currently the only type of authenticators supported, the credential IDs are opaque blobs from the perspective of the client, so we are not really in a position to tell which credential IDs [1] might belong to the authenticator unless we try them on the authenticator, but that step is performed well inside the authenticatorGetAssertion operation.

Adam, Arnar, let us know if you interpret the spec differently.

[1]: In Chromium, we are also not currently storing any information for previously used credential IDs.
The spec does say that right now, but there is an issue filed against the spec to change the wording to match the behavior of the U2F cryptotoken extension, which is what Balazs described. A similar issue is open with the CTAP2 spec as well.

https://github.com/w3c/webauthn/issues/863
https://github.com/fido-alliance/fido-2-specs/issues/509 (although I think it may have restricted visibility)
Yes, this should be working as intended. We should not allow an RP to learn what U2F authenticators are plugged (and not plugged) in without asking the user to confirm and pick which authenticator they are willing to reveal.
With regards to comment #13, we actually *do* do this filtering by talking to the authenticator. It's just that, for U2F, after discovering that an authenticator does not contain any of the credentials in allowCredentials, we send additional winking commands anyways.
I don't understand the privacy concern; `allowCredentials` does not help the RP probe the user's authenticators, it filters possible authenticators so that the user can perform the ceremony without being confused by several authentication notifications, only one of which is valid.

Maybe I should raise this to the github page for clarification.
It does: Let's assume we do filter based on the allowCredentials: An RP that wishes to test if an authenticator with keyhandle X is plugged in will send a request naming it in the allowCredentials list. If that request does not fail immediately, then they know it is plugged in - before the user has tapped it.
Arnar, it actually won't fail immediately even if that authenticator is not plugged in. It will just wait for the length of timeout (because the client is potentially waiting for hotplugged authenticators).
I was under the impression that the the reason that consent is requested for authenticators that don't have any of the 'allowCredentials' is for usability.

Comment 21 by e...@yubico.com, Apr 13 2018

>If that request does not fail immediately, then they know it is plugged in - before the user has tapped it.

That was the case in earlier drafts of the WebAuthn spec - but as Kim points out, now the promise would instead wait for timeout. If the browser would not do that, and the user somehow denied the authentication (by canceling a prompt or something), then the RP could detect that the promise resolved before timeout and conclude that the user has one of the `allowCredentials`.

Could the usability issue be solved by instead showing a browser popup when the user plugs in an authenticator that doesn't have one of the `allowCredentials`? That way the user would be informed without informing the RP, and without having to start the ceremony all over.
Ah yes, Kim (and Emil) you are correct that the timeout does deal with it, and the reason we kept it was also for usability.

U2F support used to blink only those tokens that acknowledged any of the keyHandles sent by the RP. This did result in confusion, and many internal support requests when this was rolled out within Google. When an authenticator didn't blink during sign in, they didn't deduce that it wasn't registered, but rather that it (or the sign-in) was broken and give up on it.

If instead we made all of them blink, and the user taps, the RP has the chance to tell the user "No, that one is not registered", which solved a lot of issues.

Maybe this point is worth an actual user study?
@arnarb wrote:
> If instead we made all of them blink, and the user taps, 
> the RP has the chance to tell the user "No...", ...

See:
https://github.com/w3c/webauthn/issues/863#issuecomment-381205024 and following comments.

Sign in to add a comment