-
Notifications
You must be signed in to change notification settings - Fork 167
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
RPs cannot show "You've Already Registered This Authenticator" Message #806
Comments
It looks like CTAP2 is already having authenticators return |
This limitation is by design, as discussed extensively in #184, #204, #764, #687 (comment) , #629 (comment) . In summary: providing this information would allow malicious RPs to reliably identify (i.e., track) the user without consent. |
What about in the case where the user does give consent? I.e. they touch a device they want to register without realizing it has already been registered. They fully intended to give consent to its registration. |
No. The CTAP2 spec explicitly says that user consent must be gathered before an authenticator replies with |
That is a good point... Unfortunately CTAP2 specifies that consent is collected after the CTAP2_ERR_CREDENTIAL_EXCLUDED error would be returned, so the two cases are not distinguishable to the client. ...Unless the client can ask the user up front if they intend to create a credential (i.e., something like Chrome's and Firefox's "share location?" popup: "foo.com would like to register your identity, proceed?")? In that case I suppose the client could return the EXCLUDED error early without any unintended information leak. Updating the spec to accommodate that shouldn't be too hard. I don't immediately see any other ways to solve this without sacrificing the protection against the information leak. |
I think the following would work?
Option a) lets the site probe for suspected identities, although it only gets a single bit per user action. Option b) solves this problem, but gives the user the power to register an authenticator twice if they wish, which might be crappy if sites are requiring multiple authenticators for a good reason. |
A drawback of that strategy is that the authenticator will actually create the credential before the client knows to ask "are you sure?". If that was a resident credential, then some of the authenticator's (probably limited) internal storage has now been allocated to it and it may not be obvious to the user that they need to delete it (CTAP2 has no "delete single credential" command, so the client can't do this automatically either). Aside from that, I think it sounds like a good idea. I wouldn't worry about the information leak in option (a) since, as @kpaulh notes, the user evidently does intend to share the information in this case. |
CTAP2 authenticators must gather consent before replying with
The procedure @agl suggests is what we do for U2F (CTAP1) authenticators today -- they do not have resident keys. |
Well, almost. The way this has been handled for U2F is that instead of issuing another create command to get user consent, a sign request with fake data is issued. This doesn't have the side effect of creating a credential. |
I apologize, I was incorrect here. We do send another create, but with fake data. So, yes, that does have the side effect of creating a credential. |
But that side effect doesn't matter as all U2F devices I know don't actually store anything. |
Would sending a getAssertion request suffice? So, first a query to determine that the credential was previously registered, and if so, just send a getAssertion request. If there are multiple authenticators, and a user affirmatively touches a previously registered one, a getAssertion response would be received. In that case, it can be definitively be determined from the response that this was a previously registered authenticator. If a makeCredential response is received, then the authenticator is new to the RP. |
I think some of the confusion here might be from looking at the public draft of CTAP2. In the 2017-09-27 version it says:
I.e. don't wait for user presence. Sounds like that's been fixed since then and browsers could return the error directly. |
@leshi Oh, my bad - I guess I was reading an outdated draft?
@kpaulh Ah, a fake sign request is a clever way to work around it! That seems to me like a good solution: reply with some kind of I suppose that could be confusing if the authenticator has a rich interface and makes create and sign operations substantially different. I imagine that could perhaps become an issue with U2F on "Intel Online Connect", for example, but it seems minor compared to the other issues discussed here. |
Oh, right, if the EXCLUDED response from the authenticator is now guaranteed to have collected consent first, then the information leak I was talking about shouldn't happen and I see no problem with returning a unique error before the timeout ends. |
Great! What error should we return? :) |
I don't know how these error types are typically selected, so I'll defer that question to someone who does (@equalsJeffH, @selfissued, @jcjones, @akshayku?) - but I'm guessing maybe |
|
I think we need to choose from here: https://heycam.github.io/webidl/#idl-DOMException-error-names |
Looking at https://heycam.github.io/webidl/#idl-DOMException, it appears that we might be able to use the |
"ConstraintError" seems fitting, and matches other errors due to the client asking for sth that can't be done (e.g. 'requireResidentKey'). Or simply "NotAllwedError". |
I would like us to use a different error than "ConstraintError" and "NotAllowedError", so the relying party can display the appropriate error message for the user. |
https://heycam.github.io/webidl/#idl-DOMException-error-names lists further descriptions of the error types. Edit: On the other hand, |
Many RPs prevent users from registering the same Authenticator twice. RPs use specifying the already known credentials in the
excludeCredentials
during thecreate()
call, which then gets passed down intoauthenticatorMakeCredential
in theexcludeCredentialDescriptorList
. Authenticators "should not create a new credential" if they recognize a credential that they have previously minted.In reading 6.2.2, step 3.1, when the authenticator discovers that it owns one of the excluded credentials, the authenticator replies with a
NotAllowedError
:This error is then propagated to the RP by the client. In looking at step 5.1.3 step 21, we see:
As written, the spec has two problems:
The generic "NotAllowedError" is shared between lots of different error situations. This does not allow the RP to show a meaningful message to the user. Note that Google and Github (and probably many other RPs that use U2F) already give users meaningful messagers in these cases:
The lifetimeTimer will prevent this error from being responsive. Users will touch their Security Key and then stare into blank space until the timer expires.
The text was updated successfully, but these errors were encountered: