Closed Firstyear closed 1 year ago
This creates a relationship between the UVP and the registered credential.
This is a misconception. There is no such relationship. The choice of UVP (as you call it) is for the associated ceremony only, and has no lasting binding to the credential.
It affects which credentials can be used in the registration ceremony IE on FF with U2F, a UVP of Required would not select the U2F tokens since this uses CTAP1. This becomes a policy on which credentials can be registered in that ceremony, and implies to the user that a relationship here does exist. It also means that the selected policy can affect future usage of the token, and can create surprising behaviour (UVP::Preferred on chrome requesting a password with U2F, but not on FF).
Credentials are created during the registration ceremony, not used. I think you mean which authenticators may be used. Also I think it is important to separate out the capabilities of specific browsers based on their implementation level from the semantics of the WebAuthn spec. The specification itself makes no claims about what a particular browser will support, nor that the choice of userVerification setting will work with any particular browser and authenticator combination.
It is important for RPs to choose a policy that is appropriate for the use case being implemented. If the future use of the credential is not for "password-less login" scenarios, and is therefore for 2FA-scenarios there is no real point in having uv set to anything other than discouraged. Even with uv=discouraged some authenticators (particularly platform authenticators) will still solicit uv - again this is the browsers choice.
If there are both password-less login and 2FA scenarios targeted, then L2 of the WebAuthn spec has introduced residentKey=preferred (which I would also use with uv=preferred), and the credProps extension to deal with that. It doesn't mean that all browsers will implement it, but that is the way the spec is evolving to try to offer a single registration ceremony which catches "best available" authenticator coverage.
residentKey doesn't provide uv=preferred though, that's unrelated. This is however as you say, about the password-less (the token provides the MFA capabilities) and the traditional token + pw scenario. And today the spec can't handle that, but if there is a credProps extension that is able to do per-authenticator user verification policies that would certainly work. Is this something that credProps can provide, or is this an opportunity to suggest that credProps should have a UV flag associated?
At the moment I think I will have to have some UI/UX work around for this, but yes, I'd really like the situation of password-less + MFA considered. :)
Thanks,
The residentKey parameter (which supersedes requireResidentKey boolean) introduces the "preferred" semantic which is new in the spec for L2. The credProps extension may be used in conjunction, and is designed to tell the RP what was actually provisioned (a resident/discoverable credential, suitable for a usernameless login scenario or a non-resident credential suitable for second-factor). This allows the RP to then guide the user experience, e.g. to inform the user as to what scenarios they can use their new credential to achieve.
The uv policy is orthogonal to this, however if setting residentKey=preferred I would always also set uv=preferred as there is no point in provisioning a resident/discoverable credential that you want to use in a username-less login scenario without uv. Similarly if the user has a u2f-only authenticator, setting uv=required when the authenticator cannot support uv may result in a registration failure which is not what you'd be looking for if you chose to use residentKey=preferred in the first place.
I'll echo Shane's initial point: the user verification requirement is a property of the ceremony, not of a credential. For example, one might allow both UV and a conventional password as the second factor for initial sign-in, but require hardware UV for signing a legal document. Specifying separate UV requirements per credential is moot, then, because any response without UV would be rejected anyway.
As for the different login scenarios: for username-less logins you by definition cannot specify per-credential UV requirement. "Username-ful" (I guess would be the term?) logins would usually prompt for a password first anyway, and if not, you can still use uv: "preferred"
and prompt for the password afterwards if the response comes back with UV=0.
I think there is some confusion here. I'm proposing that there is a disconnect between peoples expectations and the word of the standard. I understand that today they are properties of the ceremony, but that is not how people thing about these credentials.
I also want to point out, I am not talking about username-less either. That's unrelated to my point.
My point is that when you first register a credential there are properties of that credential that could have properties assigned to it. For example you register a verified credential as an MFA source (think touchid), but you also have a yubikey with ctap1, and still require a password.
In these scenarios because the UV is part of the ceremony not the credential it's not possible to offer both credential ID's in a single authentication workflow, the client application needs to request extra data from the user to determine which credential they want to use before sending the challenge.
Sure, the word of the standard is about the UV being part of the ceremony, but the way people think about the credential and account policy is that the UV is part of the credential itself. This is pretty clearly stated in NIST SP63-800b sections 5.1.7 and 5.1.8. https://pages.nist.gov/800-63-3/sp800-63b.html . Not only that the way a user will consider this is that it's part of the credential itself, not the "ceremony".
So I think what I'm saying is that the current approach of the standard does not mesh with guidelines like NIST SP63-800b or human expectations around consistent and reproducible behaviour of their devices.
So if there is a way to set per-credential UV requests through credProps then I would be happy for that to exist, and I think the webauthn spec should be updated to recommend credProps with UV parameters over the per-ceremony behaviour that exists today. Can someone please link to references about the credProps extensions if possible to help clarify how that works?
That is not what credProps is for. The credProps extension is for an RP to discover whether or not a discoverable credential (aka resident key (deprecated)) was provisioned when navigator.credentials.create is called with residentKey: 'preferred'
There is no facility in WebAuthn to associate UV with a credential.
There is no facility in WebAuthn to associate UV with a credential.
And this is what I believe the issue in the standard is.
There is such a facility in drafts of CTAP2.1, but I don't think they're publicly available yet.
update 20-Jan-2021: CTAP2.1 RD-02 was recently publicly published
Okay, would it be viable to have this propose an extension to webauthn (irrespective of ctap version) that allows per-credential UV policy to be interpreted by the browser or client?
Do you mean that it would be backwards-compatible even with authenticators that do not themselves support per-credential UV policies? I would guess that is not viable, no. But at least that upcoming CTAP extension is already a WebAuthn extension, so we won't need to make any changes to the WebAuthn spec to support it.
CTAP2.1 allows enforcement of PIN policy per credential via CredProtect.
There is also a new alwaysUV setting that authenticators can support to always require uv for all credentials.
You can use credprotect now, but the RP needs to not send uv discouraged or the credential won't work.
I think there may be some confusion with people thinking that credprotect only applies to discoverable credentials, it applies to both that is why there is a level 3 required.
on 2020-11-11 call: We think there may be aspects of this that we can clarify in the spec, we're putting this on the L3 milestone.
Just to clarify, what is it you believe is ambiguous and needs clarification here?
I do believe that we need to clarify the connection between UV and credential creation, and the different states that credentials (and their authenticators) can arrive at depending on if it's a discoverable key or CredProtect is being used. I'm a bit confused though as to why credentials themselves should dictate their use, since the RP can decide to approve or deny the credentials as it sees fit. We shouldn't put further onus on the authenticator (or credential itself) to provide an enforcement, however this idea and reasoning should be clarified in the spec.
I'm a bit confused though as to why credentials themselves should dictate their use, since the RP can decide to approve or deny the credentials as it sees fit. We shouldn't put further onus on the authenticator (or credential itself) to provide an enforcement
I think the core of this discussion that perhaps is being overlooked is the framing. With regard to the webauthn specification, with a single authenticator attached to the browser, and the account having multiple identical authenticators associated there is no problem.
When you include the more complex scenarioes - accounts with touchid (verified MFA authenticator) as well as a yubikey + password (multiple single factors), then these can't be expressed in the workflow.
Webauthn today expresses a single userVerification policy for the entire set of all possible authenticators associated to the account. This is incompatible with advances to more rich and dynamic mixed credential policies.
The browser is fundamentally involved in this process as it describes to the authenticator if it requires verification or not. So while the RP can accept/deny based on internal knowledege, that is not reflected in the webauthn specification that the browser should be able to set per-authenticator verification requirements that match what the RP expects. This leads to surprising and inconsistent behaviour that may confuse users or lower trust in the system. In some cases depending on the RP implementation and assumptions, it may lead to verification bypass reducing MFA authenticators to single factor.
I believe that my PR #1547 may help further to express how a per-authenticator verification policy could be expressed in the webauthn standard to resolve this.
In some cases depending on the RP implementation and assumptions, it may lead to verification bypass reducing MFA authenticators to single factor.
RPs have a responsibility to use the specification properly as well. I'm not buying that the above statement is accurate unless the RP is fundamentally broken. The only way "verification bypass" occurs is if an RP forgets to check for (and enforce) the presence of the uv bit in the returned authenticatorData when it is otherwise expecting uv to be performed. If UV is a policy of the RP for a particular assertion flow, then this should always be checked at the RP as part of response message validation, regardless of what options get passed down to the client to aid with the assertion ceremony. This is outlined already in step 17 of https://www.w3.org/TR/webauthn/#sctn-verifying-assertion
I think perhaps it is fair to observe that userVerification="preferred"
is not a good choice of a default, particularly so in the case of assertion ceremonies. In fact I would go further and suggest that the RP should always explicitly choose to set this (currently optional) parameter. That's a non-normative spec change which I would definitely support.
I believe Chrome actually spits out a warning on the browser console when userVerification is not explicitly provided in a ceremony.
The webauthn authentication challenge defines a verification policy for all possible credentials the user may use. This is incompatible with a scenario where you have verified credentials and unverified credentials. The webauthn spec should list in allowCredentials, in the credential descriptor, what verification level the browser should request from the credential.
RPs have a responsibility to use the specification properly as well.
The specification does not make it clear which properties of a webauthn challenge/response are signed and verifiable, and which are not, which leads to ambiguity and a belief in properties of webauthn that may not hold. For example, userVerification, autenticatorAttachment, requireResidentKey, excludeCredentials, authenticatorTransport - these are all hints to the browser on how to behave, but as expressed in the specification, they appear to be able to provide strict requirements on the interaction. That can lead to an RP incorrectly assuming that userVerification is a trusted property, and that the response will reflect that request (and many other things).
For example, if the RP assume userVerification can not be tampered with, and sets "preferred", when they receive the response with the uv bit set to false, https://www.w3.org/TR/webauthn/#sctn-verifying-assertion states "If user verification is required for this assertion, verify that the User Verified bit of the flags in authData is set.". The RP would allow this. Because the webauthn spec does NOT direct RP's to store the UV bit from the registration ceremony in the credential because it is per ceremony instead. This means that a token registered with "preferred", that set uv bit to true, and is now "assumed" to be a self contained MFA device, can now be trivially downgraded to a SFA because the RP implemented the webauthn specification to the letter.
I think that it would be very easy for an RP to implement this specification incorrectly, and I have already seen a number of these in the wild (which I have responsibility disclosed to the affected parties). This is part of the motivation behind re-opening this issue as I have found deployments that use uv=preferred without realising that it could be bypassed.
The specification should be designed in a way that makes it difficult to use incorrectly, and able to express security requirements that are required for a modern IDM system.
Again, see my PR that addresses this with a suggestion on how to resolve this matter in the specification.
EDIT clarify a point.
The specification does not make it clear which properties of a webauthn challenge/response are signed and verifiable, and which are not, which leads to ambiguity and a belief in properties of webauthn that may not hold.
Step 20 of the verification procedure does make this clear.
No, it doesn't. See the attached screen shots. The following words are absent from both: "The values of userVerification, autenticatorAttachment, requireResidentKey, excludeCredentials, authenticatorTransport are not part of collected Client Data Json or authData, and are hints to the attached browser".
For example, even in: https://www.w3.org/TR/webauthn/#enum-residentKeyRequirement
This uses the words " the Relying Party's requirements". This language strongly encourages an implementor to believe this is a requirement that is enforced in the specification and can be relied on. Similar language exists through out the document in many areas that are not requirements. There is no indication in these parameters that they are hints and may be altered or tampered with, leading to a false sense of security.
And similar https://www.w3.org/TR/webauthn/#sctn-registering-a-new-credential does NOT recommend the storage of the uv bit from the authenticator in step 23. It is only checked in 15.
My points continue to stand that Webauthn is unable to express in an authentication ceremony a user verification policy with mixed credential types (verified and unverified).
Because the webauthn spec does NOT direct RP's to store the UV bit from the registration ceremony in the credential because it is per ceremony instead.
I don't think this is a normative spec issue at all. Whilst it may useful for RP implementations to store information from the registration ceremony with (not in) the credential such that the RP can understand whether or not uv was performed for that registration ceremony, it is even more useful for the registration ceremony to also check the uv bit, rejecting the registration ceremony if uv is required for that type of registration. That is also a required validation documented in the registration ceremony - specifically step 15 of https://www.w3.org/TR/webauthn/#sctn-registering-a-new-credential.
I truly believe the fundamental issue here is not with the specification's semantics, but with false assumptions.
I truly believe the fundamental issue here is not with the specification's semantics, but with false assumptions.
Okay. In that case, please tell me how I can issue a webauthn authentication challenge to a client, where they have:
Notes:
@Firstyear Can I suggest that you take this over to WebAuthen Adoption Community CG
Agree with @nadalin - the adoption community is the right place for this discussion. I do have a POV on the scenario:
I would not try and implement such a scenario with a single WebAuthn call - it seems awfully prone to end user confusion.
w.r.t. the Yubikey part of the scenario, I don't know precisely what was meant by "a password to be issued after" - but assume it is meant to say that the user should also supply a password after.
If I were to attempt such a scenario I would set userVerification=discouraged in the WebAuthn call, supply an empty allowCredentials list (because the user has not yet been authenticated then none can be used), and on receiving an assertion response I would check the uv bit in the supplied authenticatorData to then make a determination as to whether to additionally require a password or not.
When using TouchID, uv should be set in the authenticatorData if the user was verified, even if the RP set discouraged for userVerification when offering it's parameters to the client.
Agree with @nadalin - the adoption community is the right place for this discussion.
I disagree. This is not an adoption issue, but a specification issue.
I do have a POV on the scenario:
I would not try and implement such a scenario with a single WebAuthn call - it seems awfully prone to end user confusion.
I believe that it is more confusing to prompt a user first to which of their credentials they should use, rather than just "use any webauthn credential, then we work out what else you need next.
When using TouchID, uv should be set in the authenticatorData if the user was verified, even if the RP set discouraged for userVerification when offering it's parameters to the client.
Okay, let's assume then it's a second yubikey - something can won't always set UV.
The point is I want this work flow:
present any webauthn token you own:
if userVerified:
return
else:
prompt for further factors
Today that's not possible to express in webauthn. Please just read the PR I sent.
The fundamental issue seems to be that you believe that userVerification is a property of each interaction regardless of what credentials are involved. I am requested that userVerification is a property of the credential after registration.
And this manifests that in registration you express a userVerification policy for the single credential involved. But in authentication you must express a policy that encompasses all possible credentials that could be used. This eliminates the possibility of mixed verified and unverified credentials in a webauthn operation, and the RP making further decisions based on that.
The extension I propose in my PR allows both to work.
EDIT: Shane and I have planned to meet to discuss this which may be quicker/easier. Thanks!
on 2021-01-27 call: we ought to close PR #1547. @sbweeden will add a comment here with input from the submitter @Firstyear on non-normative suggestions for L3.
Two suggestions from out of band discussion with @Firstyear for non-normative changes that would help RP developers:
Step 16 of Registering a New Credential may be best moved to between 21/22 because before that point most implementations won't have access to the credential alg type.
An explanatory note for RP developers that there is value in storing against the user's account not just the credential id and public key but also other attributes discovered during the attestation ceremony such as the uv bit from authenticator data, attestation data (if attestation is performed), and any extension data. This will assist RP's in making future policy decisions and determining the best WebAuthn parameters for assertion ceremonies.
Intention is that a future PR (in L3 timeframe) may be submitted to address.
@Firstyear - I think we could leave the issue open and just close the PR if you want to track the items above.
@sbweeden I'm planning to open new issues/pr for these items :) It's in my todo list so it won't be forgotten.
not understanding the discussion, i found the introduction here describing the challenge from a users point of view: https://fy.blackhats.net.au/blog/html/2020/11/21/webauthn_userverificationpolicy_curiosities.html
In the meantime I swapped browsers from Firefox to Edge and started to notice some odd behaviour when logging into my corporate account - my yubikey began to ask me for my pin on every authentication, even though the key was registered to the corp servers without a pin. Yet the key kept working on Edge with a pin - and confusingly without a pin on Firefox.
and
Webauthn fully allows this. This is because user verification is a property of the request/response flow, not a property of the device.
This creates some interesting side effects that become an opportunity for user confusion. (I was confused about what the behaviour was and I write a webauthn server and client library - imagine how other people feel …).
@soloturn Hey there - I'm the author of that blog, and the original issue reporter :)
I've changed my mind on this, I think we should give better guidance on how to use userVerification: "preferred"
. In particular that if a credential has at some point been used with UV=1
, then when userVerification: "preferred"
the RP SHOULD verify that UV=1
in that response. I maintain that UV is primarily a property of the ceremony, but not only of the ceremony in the case of userVerification: "preferred"
. Our position has been that RPs should know to enforce UV=1
if they're claiming to do MFA but not prompting for a password, but we could be more explicit about the "preferred"
case. As @Firstyear has correctly pointed out many times, users expect that when they are prompted for UV it is also enforced on the server. Even if a password has also been checked and UV is not strictly necessary, we should instruct RPs to enforce the flag in this case where it's likely that UV ended up performed anyway.
I have some ideas for a new section named something like "When and how to validate User Verification", covering the above and some more of the nuance around this. For example, that UV=1
can't be relied on for MFA the first time you see UV=1
with a given credential, only from the second time forward. The §7 RP operations would refer to this new section in the UV validation step.
This also ties into #1556 - sorry for leaving that hanging, looks like it was buried under other discussions and forgotten.
"preferred"
value can be relaxed a bit to capture the notion that the RP might conditionally enforce UV depending on the credential used.I've changed my mind on this, I think we should give better guidance on how to use
userVerification: "preferred"
. In particular that if a credential has at some point been used withUV=1
, then whenuserVerification: "preferred"
the RP SHOULD verify thatUV=1
in that response. I maintain that UV is primarily a property of the ceremony, but not only of the ceremony in the case ofuserVerification: "preferred"
.
I think the important distinction here is that while it may be a property of the ceremony, the RP needs to capture that UV state from registration to know when and if they are able to validate that property during any subsequent ceremony.
So I'm extremely happy to see this post, and this change in approach! Thank you! 🎉
@emlun Want me to attempt some draft updates for this in a PR then?
For example, that UV=1 can't be relied on for MFA the first time you see UV=1 with a given credential, only from the second time forward. The §7 RP operations would refer to this new section in the UV validation step.
To address this specifically, I think this actually is a reflection of an issue with CTAP2.0, which forces UV=1 under discouraged but then won't apply UV during authentication under discouraged. Is this why you mention that you have to trust-on-first-use the UV from authentication?
There is a different approach that is cleaner, which is that if the RP stores the UV policy that was requested during registration, you can use that along with the state of UV=1 from authentication to make a decision.
@Firstyear I have a draft ready, but I haven't yet opened a pull request because it builds on PR #1746 and a few more larger restructurings which I'd like to have reviewed on their own first. But you can take a look on the branch in my fork if you're curious. There's no preview and diff automatically available, but you can build the spec yourself (see the README) if you want to.
CTAP2.0, which forces UV=1 under discouraged but then won't apply UV during authentication under discouraged. Is this why you mention that you have to trust-on-first-use the UV from authentication?
No, it's because UV=1 does not identify the user to the RP, it only tells the RP it's the same user (PIN sharing etc. notwithstanding) as the last time UV=1 was seen on that credential. So UV=1 does not suffice as a second factor if UV=1 has never been seen with that credential before, because there's no guarantee that it's the same user operating the authenticator as before.
@Firstyear I have a draft ready, but I haven't yet opened a pull request because it builds on PR #1746 and a few more larger restructurings which I'd like to have reviewed on their own first. But you can take a look on the branch in my fork if you're curious. There's no preview and diff automatically available, but you can build the spec yourself (see the README) if you want to.
Thanks, I'll take a look soon.
CTAP2.0, which forces UV=1 under discouraged but then won't apply UV during authentication under discouraged. Is this why you mention that you have to trust-on-first-use the UV from authentication?
No, it's because UV=1 does not identify the user to the RP, it only tells the RP it's the same user (PIN sharing etc. notwithstanding) as the last time UV=1 was seen on that credential. So UV=1 does not suffice as a second factor if UV=1 has never been seen with that credential before, because there's no guarantee that it's the same user operating the authenticator as before.
Ahh yes. That's also true. But that's a bigger issue with the attitude that credentials are "ceremony bound" rather than being something that persists and has a longer lifespan. Humans don't think about a set of "keys to their house" as having ceremonies with the lock, they consider that the key and that lock are intertwined and matched. The same way that a password to a website is a specific identity to that site.
The entire notion that UV can change between registration and authentication (like ctap2.0 does under discouraged) really undermines this human approach to credentials, as does the fact that UV=1 can "suddenly" appear during the lifecycle of a credentials existence.
Hi there,
I have noticed a potential issue in the construction of UserVerificationPolicy with regard to PublicKeyCredentialCreationOptions and PublicKeyCredentialRequestOptions.
During the generation of a credential, this uses the UserVerificationPolicy (UVP) given to the AuthenticatorSelectionCriteria and embedded into PublicKeyCredentialCreationOptions. This creates a relationship between the UVP and the registered credential.
However, during an authentication, PublicKeyCredentialRequestOptions embeds the UVP in the top level dictionary, and the set of allowCredentials contains the set of credential ids that can proceed. This creates a relationship where the UVP is related to the authentication operation.
This can lead to a situation where a credential that was registered with verification, can then be used as an unverified credential in future operations. Additionally, one could register a credential with UVP::Required, and another with UVP::Discouraged, but in a future authentication this creates an ambiguity - do you require UVP::Required, and have the credential with discouraged now require verification? Or do we do the authentication with UVP::Discouraged, making the verified credential "un-verified". In the situation you use UVP::Preferred, this still creates ambiguity such as with CTAP1/2 where the credential can now become verified in some browsers, and remains unverified in others.
A possible solution is to treat the UserVerificationPolicy as "per user" and applies blanket to all tokens associated to the user, but this also reduces flexibility. Consider that an U2F token which was UVP::Discouraged at registration may be used with a password, but the user may also have a verified token that use used a sole source of MFA. The authentication flow should be that the user conducts a webauthn authentication first, and then based on that result and which credential was used we choose to request the password or not. But if we use UVP::Preferred, we now are verifying the U2F token adding an unnecessary step to the workflow.
I'm sure that it may be difficult to achieve now, but I would suggest that UVP should be moved to PublicKeyCredentialDescriptor so that in the set of allowedCredentials the browser/client, is able to determine based on which credential we are selecting the method to proceed for verification of that individual token.
Alternately, it would be potentially beneficial to consider this situation and how a diverse array of webauthn tokens can be associated to a single account, and how that interacts with the UVP and to provide recommendations accordingly. As webauthn exists in conjunction with other authentication mechanisms it should be considered how this is assembled into complete MFA systems such as a UVP::Required Token for a user, and a UVP::Discouraged Token + Password that can co-exist and have policies able to express this.
Thanks,
5.4 https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialcreationoptions 5.4.4 https://www.w3.org/TR/webauthn/#dictdef-authenticatorselectioncriteria 5.5 https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialrequestoptions 5.10.3 https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialdescriptor
update 20-Jan-2021: see also -- https://fy.blackhats.net.au/blog/html/2020/11/21/webauthn_userverificationpolicy_curiosities.html