w3c / webauthn

Web Authentication: An API for accessing Public Key Credentials
https://w3c.github.io/webauthn/
Other
1.17k stars 169 forks source link

Clarify browser behavior when an authenticators return equivalent of "InvalidStateError" #1888

Closed arnar closed 9 months ago

arnar commented 1 year ago

In the CreateCredential algorithm, step 20 says that if any authenticator returns an equivalent of "InvalidStateError", the browser should cancel any other outstanding authenticator requests and return ISE back to the caller. (Note that the authenticator steps for create say that an authenticator must collect user consent for the create before returning an ISE for a match on the excludeList)

This makes sense, because it is reasonable for an RP to want to treat this case as success: The user asked to create a credential, then they selected and approved creation on a specific authenticator, but the authenticator they selected already had a credential. That means they are already in the state they were trying to get in to. E.g. google.com renders a message here saying roughly "You're all set on this device."

However, some clients currently don't immediately return an ISE in this case, but rather either a) render an error message saying that a credential already existed on this authenticator, and offer the user to return to start and try again with a different authenticator, or b) fall back to an alternative transport.

Chromium does the former, showing a dialog with a "try again" CTA; and Windows Hello does the latter: E.g. if a platform credential is found to be a match on the excludeList (after collecting the PIN), it falls back to "Insert your Security Key now" instead of returning.

We'd like to propose somehow setting a norm that aligns the behaviors with the language in the spec, and possibly add a justification with an appropriately placed note in the spec.

Proposed Change

Add a note, e.g. following this note, stating that an immediate ISE should be returned rather than retrying other authenticators, so that RPs can choose whether it is handled as success or by offering the user to try other authenticators.

akshayku commented 1 year ago

For local platform, it makes sense to return immediately because there is no other option. For external security keys, user may want to user another security key, but plugged in another key because maybe they all look alike, or user accidently inserted an already created one. We try to strive for the user to succeed.

arnar commented 1 year ago

Right, that is the logic for the current implementations, but it is only controlled by the authenticatorAttachment preference in the request. So this applies to requests where the user might do hybrid now as well. Hybrid flows are high touch, and it is unlikely that the user has alternative phones etc. to satisfy the request. So I don't think that "Try again?" logic is helpful for those users.

In comparison to those cases, we expect SK usage, and in particular users with multiple SKs to be rare. And the RP can equally help the user enter a try-again flow if they want as well.

So I think currently this behavior is not helping users overall.

Note that my motivation for the proposal is also because I think we should strive for the user to succeed. Unfortunately the browser must fall back to very generic language in these prompts and we've seen them be unhelpful more than we've seen them be helpful.

MasterKale commented 1 year ago

However this thing goes I'd like to emphasize how useful it is as an RP to get ISE on an excludeCredentials collision, and hope that if the browser and/or platform continue to own the WebAuthn experience that an ISE continues to get returned even if a user clicks Cancel on a, "sorry, you already registered that" message that the browser/platform displays. Otherwise all that RP's would be left with is the signal indicating the user canceled out of the ceremony with no idea that it was because the authenticator was already registered.

emlun commented 1 year ago

I think I agree with @MasterKale. I would put the ask as:

Does that match up with what you're saying, @MasterKale?

(I currently have no opinion on whether the browser should offer a retry option or should always return on first failure.)

MasterKale commented 1 year ago

Does that match up with what you're saying, @MasterKale?

Catching up, yes, I think your logic holds up to what I'd like to see happen if this moves forward.

arnar commented 1 year ago

Sure, that sounds fine with me. But the primary ask in this issue is that if a local credential matches an exclude list entry, and the user performs its UV ceremony (which already should be offered before any external authnr interactions), then immediately return ISE and don't offer to retry with other authenticators.

I'm ok if requests with attachment=cross-platform offer some retry options, but I don't think they should. In general we should try and reduce the already complex branching logic in the common UX.

arnar commented 1 year ago

(I am on leave until Sept 18 btw so replies from me here will be sporadic. Tony, feel free to reassign if needed, otherwise I can tend to this when I'm back.)

MasterKale commented 9 months ago

From WG meeting @ Jan 10: Closing this out as the spec already states ISE should be raised when there's an excludeCredentials hit.