bitwarden / clients

Bitwarden client apps (web, browser extension, desktop, and cli).
https://bitwarden.com
Other
9.29k stars 1.25k forks source link

Passkey not found #6764

Closed TheRavenNL closed 11 months ago

TheRavenNL commented 1 year ago

Steps To Reproduce

  1. Go to 'google.com'
  2. Create and store a passkey in Bitwarden
  3. Close the browser
  4. Start the browser and go to 'google.com' and try to login with a passkey

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

Neonwarden commented 1 year ago

Hi there,

I attempted to reproduce your issue and was unable to do so. Is your vault unlocked at the time of signing into Google?

We use GitHub issues as a place to track bugs and other development related issues. If your issue persists, please write us back using our contact form, so we can continue troubleshooting: https://bitwarden.com/contact/

You can include a link to this issue in the message content.

Alternatively, you can also search for an answer in our help documentation (https://bitwarden.com/help/) or get help from other Bitwarden users on our community forums (https://community.bitwarden.com/c/support/).

The issue here will be closed.

Thanks!

kzzalews commented 1 year ago

@Neonwarden I can reproduce the issue with google.com on my side. With the same configuration (Win11 and Edge). Would you like me to gather more info? How can I do that?

It's important to notice that passkey stored with Bitwarden works perfectly when tested on Google's passkey configuration page for my account [1]. It stops working (doesn't show up as available for selection in Bitwarden), when I try to use it during login on google.com page.

Also, Bitwarden's entry for my Google account is for https://accounts.google.com URI, if this helps.

[1] https://myaccount.google.com/signinoptions/passkeys

thericle commented 1 year ago

I have the exact same issue as described in the 2 posts above. I use Google Chrome on Windows 11.

sammbw commented 1 year ago

Hi there,

Thanks for your additional reports.

I was able to reproduce this issue myself, and I have flagged this to our engineering team.

If you wish to add any further information/screenshots/recordings etc., please feel free to do so at any time - our engineering team will be happy to review these.

Thanks once again!

TheCrazyMax commented 1 year ago

Hi there,

Thanks for your additional reports.

I was able to reproduce this issue myself, and I have flagged this to our engineering team.

If you wish to add any further information/screenshots/recordings etc., please feel free to do so at any time - our engineering team will be happy to review these.

Thanks once again!

Thanks, I'm happy that my video recording sent by email helped to reproduce the issue :)

OldMacDonald1 commented 1 year ago

I have noted the same problem. The problem is specific to MS Windows (and only when loging in to my Google account). I used Chrome, Brave and Edge. I can login successfully to Google using the passkey stored in BW on MacOS and also Linux Debian, but fails when using Windows.

image

ttallberg commented 1 year ago

Same problem here logging in to google account on Windows 11 with Edge browser. Works OK on macOS Sonoma and Edge.

jtackaberry commented 1 year ago

Same behavior here with Windows 10 22H2 and Firefox 119 with Bitwarden 2023.10.1 installed (as a sideload via about:debugging since Mozilla hasn't approved 2023.10 on Mozilla Addons yet).

kreake commented 1 year ago

Same here (Win 11, Edge 119.0.2151.44, Bitwarden 2023.10.1): image

SergeyBashashin commented 1 year ago

Steps To Reproduce

  1. Go to 'google.com'
  2. Create and store a passkey in Bitwarden
  3. Close the browser
  4. Start the browser and go to 'google.com' and try to login with a passkey

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

  • [x] I understand that work is tracked outside of Github. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.

having exactly the same issue

tomasztrzos commented 1 year ago

I have exactly same issue on macos.

isaumya commented 1 year ago

I am also facing this exact same issue on Win 11 + Chrome.

Moreover, as the Bitwarden Android App update is here which now supports passkeys, I even tried with my Android Chrome Incognito window. Same Google issue remains on my phone as well.

kriswilk commented 1 year ago

I am also facing this exact same issue on Win 11 + Chrome.

Moreover, as the Bitwarden Android App update is here which now supports passkeys, I even tried with my Android Chrome Incognito window. Same Google issue remains on my phone as well.

Correct me if I'm wrong, but I don't think the Android app can do anything with passkeys yet, other than show that you've saved one in a vault entry. Mobile passkey functionality is coming in a future update.

isaumya commented 1 year ago

Correct me if I'm wrong, but I don't think the Android app can do anything with passkeys yet, other than show that you've saved one in a vault entry. Mobile passkey functionality is coming in a future update.

Sorry! That's my bad. The Android app shows the passkey for the login item but actually doesn't work. It just shows that passkey is there for that login. That's it.

davxy commented 1 year ago

I face this issue when using 2FA with security key (Yubikey). After that I inserted user and pass. The "Passkey not found" pop-up appears. The expected behavior was to touch the key to unlock it

ybce commented 1 year ago

Same issue on MacOS, on sites where I used to use my fingerprint as a second factor, the popup comes up and the system fingerprint prompt doesn't show anymore. I didn't save any passkeys in the past in bitwarden related to these sites.

Edit: Workaround seems to click Use browser in the bottom left corner of the popup, this brings up the system prompt for fingerprint and I assume for yubikey as well.

kriswilk commented 1 year ago

Same issue on MacOS, on sites where I used to use my fingerprint as a second factor, the popup comes up and the system fingerprint prompt doesn't show anymore. I didn't save any passkeys in the past in bitwarden related to these sites.

Edit: Workaround seems to click Use browser in the bottom left corner of the popup, this brings up the system prompt for fingerprint and I assume for yubikey as well.

This is not the issue we're discussing here. This thread is about the situation where a user creates a passkey for Google, has it saved in BW, but BW reports "no passkey found" when subsequently trying to log into Google.

clrizzi commented 1 year ago

Same problem here, using Firefox and Bitwarden on Windows.

TheUntouchable commented 1 year ago

Okay, and i thought its just me.. Same on FF 119.0.1 64bit and Bitwarden Extension 2023.10.1 and Windows 11 Else its working quite well with Github and other sites.

johnnykang commented 1 year ago

2023.10.2 chrome extension is out. Seems to 'partially' fix the Google passkey issue. I still can't get the account.google.com to detect the passkey on 'bitwarden' client, but it does fallback to Windows Hello or Yubikey now.

PS:

When setting up the Passkey in the Account setting page, it is now able to add and detect and verify the Bitwarden passkey. However, when it is on the login page (account.google.com, where you input your username and choose passkey to proceed), Bitwarden passkey is NOT detected, and it falls back to the native implementation, Windows Hello or Yubikey. Just NOT Bitwarden extension.

TheUntouchable commented 1 year ago

Browser v2023.10.2

Automatically fall back to the native "use browser" option when no passkeys exist in Bitwarden for a given website. The vault must be unlocked for us to know no passkeys exist.
Fall back to the native "use browser" option when closing the Bitwarden passkey window.
Respect excluded domains list (under Settings) before showing Bitwarden passkey options for a given website.
**Fixes to iCloud and Google passkey login. There is still a known issue with Google on some Windows device configurations.**

https://github.com/bitwarden/clients/releases

kriswilk commented 1 year ago

2023.10.2 chrome extension is out. Seems to 'partially' fix the Google passkey issue. I still can't get the account.google.com to detect the passkey on 'bitwarden' client, but it does fallback to Windows Hello or Yubikey now.

My browser extension also updated to 2023.10.2 (Edge, Windows 11). Now BW doesn't come up at all, only a QR code presented by the browser allowing me to sign in from the device that hosts the passkey.

This new behaviour is in line with what @kspearrin announced on reddit here. Specifically:

"Automatically fall back to the native "use browser" option when no passkeys exist in Bitwarden for a given website. The vault must be unlocked for us to know no passkeys exist."

Basically, BW still thinks there's no passkey for google but now it's just not announcing it in a dialog box.

Waiting for a proper fix...

EDIT: @TheUntouchable beat me to it... :)

isaumya commented 1 year ago

Not sure what Google did which is so different that Passkey is only broken for Google. This is so weird. This update is a band-aid fix.

TheCrazyMax commented 1 year ago

2023.10.2 chrome extension is out. Seems to 'partially' fix the Google passkey issue. I still can't get the account.google.com to detect the passkey on 'bitwarden' client, but it does fallback to Windows Hello or Yubikey now.

PS:

When setting up the Passkey in the Account setting page, it is now able to add and detect and verify the Bitwarden passkey. However, when it is on the login page (account.google.com, where you input your username and choose passkey to proceed), Bitwarden passkey is NOT detected, and it falls back to the native implementation, Windows Hello or Yubikey. Just NOT Bitwarden extension.

That's true for the fallback. But the behaviour was already there on 2023.10.0 for the account setting page finding it, but not the login page :)

TheCrazyMax commented 1 year ago

Not sure what Google did which is so different that Passkey is only broken for Google. This is so weird. This update is a band-aid fix.

The passkey from Google is not different form others. And other password managers or Windows Hello etc are handling it correctly. I don't know what the issue is exactly, but Google is sending the correct relying party ID and Bitwarden is not finding it on the login page for now.

"fido2Credentials":[ { "credentialId":"[removed]", "keyType":"public-key", "keyAlgorithm":"ECDSA", "keyCurve":"P-256", "keyValue":"[removed]", "rpId":"google.com", "userHandle":"[removed]", "counter":"3", "rpName":"Google", "userDisplayName":"[removed]", "discoverable":"true", "creationDate":"2023-11-02T15:33:07.027Z" } ]

OldMacDonald1 commented 1 year ago

The passkey from Google is not different form others. And other password managers or Windows Hello etc are handling it correctly. I don't know what the issue is exactly, but Google is sending the correct relying party ID and Bitwarden is not finding it on the login page for now.

"fido2Credentials":[ { "credentialId":"[removed]", "keyType":"public-key",

Can you repeat that on the Manage Your Google Account->Security->Passkeys page because the "Give it a try" test button does work with BW (even on Windows). Then you can compare working and non working fido2credentials

trmartin4 commented 1 year ago

We have been investigating this internally, and we believe that this behavior is due to an inconsistent implementation of WebAuthn on the part of Google. We are still researching, but our current prerequisites for this behavior are:

  1. The affected user is running Windows
  2. The account has both a Security Key (non-discoverable, 2FA key) and a Passkey (discoverable) registered on their Google account, with the Security Key not in Bitwarden and the Passkey in Bitwarden.

In that scenario, Google does not properly supply the credential ID for the registered Passkey when you attempt to authenticate. The only credential ID that is supplied is for the 2FA Security Key, not the Passkey. This results in the Bitwarden extension showing "No credential found" (in 2023.10.1) or reverting to the default browser behavior (in 2023.10.2). If no credential ID were supplied, Bitwarden would match on relying party ID, but per the WebAuthn spec if a credential is supplied the authenticator must respect that list and not provide credentials that are not on the list.

Interestingly, this behavior is not exhibited on the "Give it a try" button, so the credential is found in that case.

We are still actively researching this and will update if there are any updates.

isaumya commented 1 year ago

Thanks a lot for the explanation @trmartin4. I truly hope you and the team find a resolution soon. We all are eagerly waiting. I know it is insanely hard to work with Google as there is no way to contact them and ask them why they are doing this weird thing. They just do it and don't care about the rest.

kriswilk commented 1 year ago
  1. The account has both a Security Key (non-discoverable, 2FA key) and a Passkey (discoverable) registered on their Google account, with the Security Key not in Bitwarden and the Passkey in Bitwarden.

For the record, I do not have a security key, nor do I have one registered with my google account. But I definitely experience the problem reported by @TheRavenNL.

So having a security key does NOT appear to be a prerequisite for this behaviour.

TheCrazyMax commented 1 year ago

The passkey from Google is not different form others. And other password managers or Windows Hello etc are handling it correctly. I don't know what the issue is exactly, but Google is sending the correct relying party ID and Bitwarden is not finding it on the login page for now. "fido2Credentials":[ { "credentialId":"[removed]", "keyType":"public-key",

Can you repeat that on the Manage Your Google Account->Security->Passkeys page because the "Give it a try" test button does work with BW (even on Windows). Then you can compare working and non working fido2credentials

Yes that's what I'm saying from the beginning :) And I told that to Bitwarden support to make them reopen this issue :) But the relying party is "google.com" so it should work on both, but Bitwarden is not detecting it on the login page

TheCrazyMax commented 1 year ago

We have been investigating this internally, and we believe that this behavior is due to an inconsistent implementation of WebAuthn on the part of Google. We are still researching, but our current prerequisites for this behavior are:

  1. The affected user is running Windows
  2. The account has both a Security Key (non-discoverable, 2FA key) and a Passkey (discoverable) registered on their Google account, with the Security Key not in Bitwarden and the Passkey in Bitwarden.

In that scenario, Google does not properly supply the credential ID for the registered Passkey when you attempt to authenticate. The only credential ID that is supplied is for the 2FA Security Key, not the Passkey. This results in the Bitwarden extension showing "No credential found" (in 2023.10.1) or reverting to the default browser behavior (in 2023.10.2). If no credential ID were supplied, Bitwarden would match on relying party ID, but per the WebAuthn spec if a credential is supplied the authenticator must respect that list and not provide credentials that are not on the list.

Interestingly, this behavior is not exhibited on the "Give it a try" button, so the credential is found in that case.

We are still actively researching this and will update if there are any updates.

Same as @kriswilk here, no security key linked to my Google Account, only passkeys.

porzana commented 1 year ago

When I spoof my user agent to Firefox 113 MacOS and clear my cookies (if using the extension "User-Agent Switcher and Manager" you also have to remove accounts.google.com from the blacklist), I can sign in using my passkey. So this confirms that Google changes their behavior based on the user's OS.

trmartin4 commented 1 year ago

@TheCrazyMax @kriswilk, would you be able to share the number of passkeys you have registered on your Google accounts and stored outside of Bitwarden, and whether they are platform credentials or cross-platform credentials? We have not been able to replicate that behavior but I would like to make sure we have exactly the same replication steps. We are relying on the behavior of Google in their role as the relying party and we can't anticipate how their responses may differ and what criteria they may be using.

porzana commented 1 year ago

Even though I have not manually added any additional passkeys, there is an "automatically created passkey" on my Android phone that I cannot delete.

porzana commented 1 year ago

Okay, so after signing out on my phone, the automatically created passkey is gone, and now I can use my Bitwarden passkey!

I signed back in on my phone, and as expected, the automatically created passkey is back and I can't sign in on Windows anymore.

It might be that on Windows, the automatically created one takes precedence, and on MacOS, the custom one does. Because Windows does not officially support passkeys yet, Google might expect that users want to use cross device authentication with their Android phone there. (Just a theory.)

TheUntouchable commented 1 year ago

All Android phones - don't ask which Android version or since when - are passkeys by default when connected to the Google account, as far as I know. I currently have three, for example. The reason for this could be that Google also wants to do get rid of passwords and this is the preparation.

porzana commented 1 year ago

Strangely, the virtual authenticator from Chrome Devtools works with the same setup. When logging calls to navigator.credentials.get WITHOUT the virtual authenticator enabled, allowCredentials only contains one element, but when enabling the virtual authenticator, it contains two public key elements. The virtual authenticator being enabled seems to change something about the environment that causes Google to correctly send both passkeys as options.

Edit: When disabling the virtual authenticator again, it still sends both, even when signing in in a different browser. So it must be set at creation time.

For reference, my virtual authenticator settings are: CTAP2 over USB, supports resident keys, supports user verification, supports large blob

porzana commented 1 year ago

I think I found the culprit. It's the transport. When it's set to usb, ble, or nfc, it works, but with internal, it doesn't.

Edit: Yup, bitwarden indeed uses internal: https://github.com/bitwarden/clients/blob/4446c09fd2d61c421b46fba9d3a825acb6e6cdce/libs/common/src/vault/services/fido2/fido2-client.service.ts#L199

Not sure whether it's best to change the transport for all websites or just for Google.

TheCrazyMax commented 1 year ago

Okay, so after signing out on my phone, the automatically created passkey is gone, and now I can use my Bitwarden passkey!

I signed back in on my phone, and as expected, the automatically created passkey is back and I can't sign in on Windows anymore.

It might be that on Windows, the automatically created one takes precedence, and on MacOS, the custom one does. Because Windows does not officially support passkeys yet, Google might expect that users want to use cross device authentication with their Android phone there. (Just a theory.)

Windows is supporting only device bound ones, but they are supported since 23H2, they were there before and now we can manage them. I don't think that this is a cause, as if you try it with 1Password, it works there without having to sign out from anywhere.

TheCrazyMax commented 1 year ago

@TheCrazyMax @kriswilk, would you be able to share the number of passkeys you have registered on your Google accounts and stored outside of Bitwarden, and whether they are platform credentials or cross-platform credentials? We have not been able to replicate that behavior but I would like to make sure we have exactly the same replication steps. We are relying on the behavior of Google in their role as the relying party and we can't anticipate how their responses may differ and what criteria they may be using.

Sure, here is a screenshot image I have the automatically created one on Android, one on Windows, one on 1Password (as a trial to compare) and one for Bitwarden

TheUntouchable commented 1 year ago

For me its looking like this, also not working: Win 11 23H2, Firefox 119.0.1, Plugin 2023.10.2 grafik

kriswilk commented 1 year ago

@TheCrazyMax @kriswilk, would you be able to share the number of passkeys you have registered on your Google accounts and stored outside of Bitwarden, and whether they are platform credentials or cross-platform credentials?

Coming back to the thread late but wanted to provide this info. My Google passkey page looks like this:

Web capture_10-11-2023_75933_myaccount google com

I see that there's a potential "fix" in #6847. Looking forward to it.

I have to wonder how this problem got overlooked before launching passkey support. Windows/Google (while owning an Android device) has got to be one of the most common combinations that anyone would use.

porzana commented 1 year ago

I also wonder what the benefit of doing this is for Google? I don't know how sending multiple allowed credentials could cause problems with a correct passkey implementation. Is it just a workaround for some browser/OS/Windows Hello bug on Google's part?

TheCrazyMax commented 1 year ago

I also wonder what the benefit of doing this is for Google? I don't know how sending multiple allowed credentials could cause problems with a correct passkey implementation. Is it just a workaround for some browser/OS/Windows Hello bug on Google's part?

Here is the specification from W3C: https://w3c.github.io/webauthn/#dom-publickeycredentialrequestoptions-allowcredentials & https://w3c.github.io/webauthn/#dom-publickeycredentialdescriptor-transports "If the user account to authenticate is already identified (e.g., if the user has entered a username), then the Relying Party SHOULD use this member to list credential descriptors for credential records in the user account. This SHOULD usually include all credential records in the user account."

=> It looks like it's due to Google asking the username, which is then using the same method as for non-discoverable credentials to find it, so it is highly recommended to specify the existing credentials in that scenario apparently

And yes, it looks like the "internal" value for transports may be an issue: https://w3c.github.io/webauthn/#dom-authenticatortransport-internal if Bitwarden is considered as a removable authenticator. Is it the case ?

porzana commented 1 year ago

There is a different, likely preferable workaround. It does violate the spec, but Windows Hello seems to do the same. It involves this logic: https://github.com/bitwarden/clients/blob/ade9e9adfeb325bf5cbeac1b0bad0d7b3b344afa/libs/common/src/vault/services/fido2/fido2-authenticator.service.ts#L212

It should maybe use both findCredentialsById and findCredentialsByRp. With this, if there is a credential specified but it's not the right one, it does not try searching for credentialy by the relying party.

Modified my PR #6847 to use this

porzana commented 1 year ago

Violates this part of the spec: https://w3c.github.io/webauthn/#dom-publickeycredentialrequestoptions-allowcredentials "If not empty, the client MUST return an error if none of the listed credentials can be used."

TheCrazyMax commented 1 year ago

Oh, wait, this is bad: "Fixing" this would violate the spec https://w3c.github.io/webauthn/#dom-publickeycredentialrequestoptions-allowcredentials "If not empty, the client MUST return an error if none of the listed credentials can be used."

To be checked, but I think that the Bitwarden fallback already implemented an error that redirects to the browser prompt (fallback). I don't remember in which commit I saw that. But we may have to adapt it from "if no passkey found in Vault for RP" to "if no passkey from given list found in Vault"

porzana commented 1 year ago

"if no passkey from given list found in Vault"

That is the way it works right now, I think, and it's correct, according to the spec. And it's also what causes it to fail with Google. Essentially, it would need to be "no passkey found in Vault or list" (which I think is equivalent to just ignoring allowCredentials entirely).

Right now it looks like one has to either change the transport to something incorrect (usb, ble, nfc) or just ignore allowCredentials. Both are workarounds that violate the spec.

The only remaining option would be to find another, hopefully compliant, way to get Google to send both credentials, or none at all. If Google sends just the Android one, to be compliant, Bitwarden has to reject the request.

What we know about the heuristic that causes Google to not send the passkey:

TheCrazyMax commented 1 year ago

"if no passkey from given list found in Vault"

That is the way it is right now. And that is what causes it to fail with Google. Essentially, it would need to be "no passkey found in Vault or list" (which I think is equivalent to just ignoring allowCredentials entirely).

Right now it looks like one has to either change the transport to something incorrect (usb, ble, nfc) or just ignore allowCredentials. Both are workarounds that violate the spec.

The only remaining option would be to find another, hopefully compliant, way to get Google to send both credentials, or none at all. If Google sends just the Android one, to be compliant, Bitwarden has to reject the request.

Do we have any example of what Google is sending ? If they are following the standards, they should send all of them in the list sorted by preference. So a possible scenario is that Android is the first one in the list and that we are only checking for that one. It's just an assumption.

porzana commented 1 year ago

Yes, we do. I logged it with const old = navigator.credentials.get; navigator.credentials.get = (x) => { console.log(x); debugger; return old.bind(navigator.credentials, x)(); }; and when the conditions listed in my comment above are met, allowCredentials only has one member, and that is the "automatically created passkey".