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

Platform authenticators and key stores #851

Closed
idamlaj opened this issue Mar 22, 2018 · 12 comments
Closed

Platform authenticators and key stores #851

idamlaj opened this issue Mar 22, 2018 · 12 comments
Assignees
Milestone

Comments

@idamlaj
Copy link

idamlaj commented Mar 22, 2018

Issue #420 (PR #708) details how a relying party who only wants platform authenticators can create authentication flows using the web authentication API:

  • Relying party creates a credential with attachment=platform
  • Relying party stores the credential ID (let's call it cred1) in HTML5 local storage
  • Next time a user wants to authenticate, relying party passes [cred1] as allowCredentials in .get(), knowing that cred1 was created as a platform credential.

This method works fine most of the time.

However, on some platforms, the key store holding the platform credential cred1 – or its decryption key, if it is a server-resident credential – may get wiped for a variety of reasons (e.g. last fingerprint removed, disabling / re-enabling screenlock, etc).

If we follow the WebAuthn specification as is, the following user flow will occur:

  • Relying party creates a credential with attachment=platform
  • Relying party stores the credential ID (cred1) in HTML5 local storage
  • Day to day, relying party authenticates the user by passing [cred1] as allowCredentials in .get()
  • One day, the user disables and re-enables the screenlock on their device. This deletes all the platform credentials in the device's key store, including cred1.
  • Next time the relying party tries to authenticate the user, the platform will not know cred1 is a platform key, so the platform will display a UI asking the user to present a security key – which they never created.
    • User will try to cancel out of this security key UI
    • Relying party will get NotAllowedError which could mean anything from "timeout" to "user canceled authentication", so they can't tell that the user is in this state.
    • Thus, user will keep getting asked for a security key they never created every time they visit the relying party web site.

Is this a scenario that the working group cares about? If so, what are the recommendations to prevent the user experience described above?

@emlun
Copy link
Member

emlun commented Mar 26, 2018

The RP will indeed get an ambiguous NotAllowedError, but that doesn't mean the RP can't show some kind of "Something wrong?" page. Just like many password forms provide a "Forgot password?" link on failed attempts, the RP can show a page to the effect of "Lost security key?" and other likely causes for the NotAllowedError. If the RP knows it's sent an allowCredentials of only platform credentials, it can make use of that information as well in trying to diagnose the problem (for example, showing the "Something wrong?" if the ceremony takes more than, say, 5 seconds, even if the actual timeout is much longer).

For example, Google's current U2F login currently shows a prominent "Having trouble?" button while waiting for the user to use their U2F key. Clicking the button allows the user to retry or try a different login method, and timeout and failure also sends the user to this same view. I think this kind of approach is very applicable to WebAuthn as well, for both platform and roaming credentials.

@nadalin nadalin added this to the PR milestone Mar 28, 2018
@equalsJeffH
Copy link
Contributor

discussed on 2018-03-28 webauthn call: @christiaanbrand acks that they have been thinking about this -- thinks their current impl ignores the spec in this case... at least on Android, they know that a "key got wiped" and so can be smarter about it, but am not sure all platforms have that info available.

@akshayku how do you know to fallback to the external authnrs in this case?

@christiaanbrand: android knows that a key existed at one time. wonders whether we ought to introduce the attachment parm to the get() request (#getAssertion). this is not optimal soln because what if user is using different profiles/personas (?).... need to think about this.

@akshayku: windows has system restore notion which wipes the entire machine and all knowledge goes away.... platformResident keys will disappear...

@christiaanbrand: there's a bunch of subtleties to this and wishes to discuss this further

@emlun
Copy link
Member

emlun commented Mar 28, 2018

Do we envision tweaking the API for this? In that case, perhaps it could be solved by adding a (non-signed) AuthenticatorAttachment attribute to PublicKeyCredentialDescriptor and AuthenticatorAttestationResponse? That would require no changes to CTAP or authenticators. Then the client could detect if allowCredentials lists only platform credentials of which none is available, although that on its own wouldn't be enough to determine whether a credential has disappeared from the current device.

I think we also need to be careful with what kind of error to throw in that case. As we've discussed before, returning an error immediately could leak identifying information. On the other hand I think that showing an immediate browser popup informing the user, without immediately resolving the promise, shouldn't be an issue.

@equalsJeffH
Copy link
Contributor

equalsJeffH commented May 2, 2018

related to issue #889

@emlun
Copy link
Member

emlun commented May 2, 2018

See also: PR #882

@selfissued
Copy link
Contributor

@akshayku suggested on the 2-May-18 call that we discuss this in the upcoming plenary.

@equalsJeffH
Copy link
Contributor

PR #882 essentially implements @emlun's suggestion above, yes?

@emlun
Copy link
Member

emlun commented May 3, 2018

Yes - I forgot that we already have a transports attribute in PublicKeyCredentialDescriptor. #882 adds an "internal" value to the AuthenticatorTransport enumeration to indicate platform credentials and adds a transports property to AuthenticatorAttestationResponse, which should be functionally equivalent to my above suggestion.

@equalsJeffH
Copy link
Contributor

equalsJeffH commented Jun 6, 2018

@agl thinks some further spec changes are necessary. see PR #882
@akshayku : we split the breakaing change and non-breaking change and will merge the non-breaking one... I will ask @idamlaj for clarification on whether he desires anything further to address his concerns.

@nadalin
Copy link
Contributor

nadalin commented Jul 6, 2018

@equalsJeffH Any update from @idamlaj

@equalsJeffH
Copy link
Contributor

equalsJeffH commented Jul 6, 2018

@nadalin -- I believe the above #851 (comment) documents @akshayku saying that he Akshay will ask @idamlaj for clarification on whether he Ibrahim desires anything further to address his concerns.

Note that PR #882 had the non-controversial/non-breaking addition of the internal enum value of AuthenticatorTransport split off into PR #903 which has been merged-to-master. Please ensure @idamlaj is aware of that as he formulates his answer.

@equalsJeffH
Copy link
Contributor

on 11-Jul call, @idamlaj elaborated on the impetus for this issue and the need for an unambiguous signal. there was much detailed discussion -- see call minutes: https://www.w3.org/2018/07/11-webauthn-minutes.html, where @idamlaj (Ibrahim) begins talking.

we decided to move this to level 2 at this time. PR #906 improves this, but does not wholly address it.

@nadalin nadalin modified the milestones: PropRec, L2-WD-00 Jul 18, 2018
agl added a commit to agl/webauthn that referenced this issue Aug 29, 2018
This change adds a `getTransports` method to
`AuthenticatorAttestationResponse` that returns the
`AuthenticatorTransport` used to perform a registration, as well as
other transports that the user agent believes that the authenticator
supports.

Fixes w3c#889
Fixes w3c#851
See also w3c#882
equalsJeffH pushed a commit that referenced this issue Feb 12, 2019
* Provide transport information during registration.

This change adds a `getTransports` method to
`AuthenticatorAttestationResponse` that returns the
`AuthenticatorTransport` used to perform a registration, as well as
other transports that the user agent believes that the authenticator
supports.

Fixes #889
Fixes #851
See also #882

* Update in light of PR discussion.

[ went ahead and merged due to no objections to doing so ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants