Closed TheRavenNL closed 10 months ago
Windows Hello seems to do exactly what I proposed, ignoring allowCredentials if none match. I tried intercepting it and only allowing a credential that I definitely do not have saved, and it still authenticates me. This does not seem to bother Google.
So, in essence, I think it might be worth diverging from the spec here. Windows Hello does so too, if I'm not wrong.
Windows Hello seems to do exactly what I proposed, completely ignoring allowCredentials. I tried intercepting it and only allowing a credential that I definitely do not have saved, and it still authenticates me. This does not seem to bother Google.
So, in essence, I think it might be worth diverging from the spec here. Windows Hello does so too, if I'm not wrong.
As Google is sending the username, that allows both a discoverable and a non-discoverable passkey to work there, so I'm wondering if Windows Hello is just using the userDisplayName ? When a username is sent, would that be a solution here as well ?
Perhaps, but as I read the spec, even if there is a credential with a matching username, we are still not allowed to use it if it is not in allowCredentials.
A compromise could be allowing non listed credentials, but showing some UI indication that the website does not prefer you use this one. Or, if there are matching credentials in the vault, but none of them are in the list, only then ignore it.
The least invasive might be to add a list of relying parties / websites that use allowCredentials incorrectly, and ignore it only for them. (I don't know of any other website that does this.)
If Google actually intended this, they would have implemented server side validation to check if a listed credential was used.
Perhaps, but as I read the spec, even if there is a credential with a matching username, we are still not allowed to use it if it is not in allowCredentials.
It looks like the same behavior has already been observed and that apparently, from the answer, some standard may not be followed https://stackoverflow.com/questions/76330542/webauthn-allowcredentials-and-credential-selection Not sure what the best solution is
There is also a similar experience here https://www.authgear.com/post/4-things-we-learned-supporing-passkeys under "User Experiences Vary Across Platforms" And some guidelines from Yubico there https://developers.yubico.com/Passkeys/Passkey_relying_party_implementation_guidance/Passkey_authentication_requests.html under "Non-discoverable credential authentication"
@limisk From there https://www.w3.org/TR/webauthn-2/#sctn-terminology I see that So for me, it means that on Bitwarden we are storing discoverable credentials for Google, but Google is sending the request in a non-discoverable mode. But the spec is saying that it should be usable in both cases, so my guess is that we could safely ignore the allowCredentials for Google (and maybe others or all of them ?) and look for a passkey that matches both the rpId "google.com" and the userDisplayName which is the account email address stored in the passkey.
If we match the rpId, it should be safe as it's the mechanism that is there to avoid phishing and other kind of attacks. Can you easily try that solution on your side ?
@limisk I'm also wondering about the "internal" value that you were speaking about: this demo site https://webauthn.me is the best that I found a few months ago and it looks like it does not work with Bitwarden because it can not read the "authenticatorAttachment" value, and Bitwarden is not going to the Fallback method there.
=> Isn't it also a part of the issue, that we may not be registered as a correct authenticator attachment type ? If I disable the Bitwarden extension, it's going to the Windows Hello Prompt and it works
I just found that the line saying "if there is no allowed credential the client must return an error" was only added in WebAuthn 3, which is still a draft. In WebAuthn 2 this is simply left unspecified, and I guess it could be interpreted either way. I don't think the note at w3.org/TR/webauthn-2/#sctn-terminology conflicts with either interpretation, as it could just be taken to mean "discoverable credentials can be used, if they are in the list".
and look for a passkey that matches both the rpId "google.com" and the userDisplayName which is the account email address stored in the passkey. The display name should never be used to look for a key. That's what the id field is for. But yes, that could be useful.
Either way, I'm not a Bitwarden developer, and I don't think there's any clearly correct option here, so I don't have much to add anymore.
Ok thank you :)
@trmartin4 Can you help with that ?
I'm also wondering about the "internal" value that you were speaking about: this demo site webauthn.me is the best that I found a few months ago and it looks like it does not work with Bitwarden because it can not read the "authenticatorAttachment" value, and Bitwarden is not going to the Fallback method there.
Hmm, this might be a separate bug with the fallback code. Bitwarden definitely sends an authenticatorAttachment ("cross-platform").
I honestly don't know how useful this discussion is, I think the Bitwarden team is investigating this separately internally and they have probably arrived at the same conclusions as we have :) I was just curious and had time on my hands, so I decided to look into it.
Thank you all for the feedback. Everything you have identified corresponds with the research we have done internally. We would prefer to understand the intent of the behavior from Google in this case before adjusting the transports
. Ignoring the allowCredentials
when provided would or misrepresenting the transports
would be a last resort, as we would like to obey the letter and spirit of the WebAuthn spec as much as possible in our implementation.
As for the issue on webauthn.me, I believe that is the same issue discussed here, and we will be able to address that separately.
Thank you all for the feedback. Everything you have identified corresponds with the research we have done internally. We would prefer to understand the intent of the behavior from Google in this case before adjusting the
transports
. Ignoring theallowCredentials
when provided would or misrepresenting thetransports
would be a last resort, as we would like to obey the letter and spirit of the WebAuthn spec as much as possible in our implementation.As for the issue on webauthn.me, I believe that is the same issue discussed here, and we will be able to address that separately.
Any update on this?
Thank you all for the feedback. Everything you have identified corresponds with the research we have done internally. We would prefer to understand the intent of the behavior from Google in this case before adjusting the
transports
. Ignoring theallowCredentials
when provided would or misrepresenting thetransports
would be a last resort, as we would like to obey the letter and spirit of the WebAuthn spec as much as possible in our implementation. As for the issue on webauthn.me, I believe that is the same issue discussed here, and we will be able to address that separately.Any update on this?
Yeah... It's fixed by #6847
Same issue but for different website. I'm trying to authenticate using cisco duo. The error occurs on the following platforms:
Problem does not occur on my Ubuntu 23.10 installation using Firefox.
Is this related to #6847? I.e. cisco does things the same as google causing Bitwarden to not find the passkeys? Sorry, I don't fully understand the technicalities of the issue this PR fixed, so I might be mistaken.
Steps To Reproduce
Expected Result
Passkey pops up in the plugin window
Actual Result
Passkey is not found
Screenshots or Videos
No response
Additional Context
The passkey is visible in the vault.
Operating System
Windows
Operating System Version
Windows 11
Web Browser
Microsoft Edge
Browser Version
118.0.2088.76
Build Version
2013.10.0
Issue Tracking Info