bitwarden / clients

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

Websites raising `Invalid 'user.id' length` at init #8756

Open LeoColomb opened 4 months ago

LeoColomb commented 4 months ago

Steps To Reproduce

For example, with Sentry.io (https://github.com/getsentry/sentry):

  1. Bitwarden extension logged in
  2. Be authenticated on Sentry
  3. Go to https://sentry.io/settings/account/security/mfa/u2f/enroll/
  4. For testing, the Retry button can be clicked as much as necessary.

Another example, with Gandi.net:

  1. Bitwarden extension logged in
  2. Be authenticated on Gandi.net
  3. Go to Account > Authentication > MFA > Add new
  4. For testing, the Retry button can be clicked as much as necessary.

Expected Result

Bitwarden to open a popup to create and save a passkey.

Actual Result

Nothing, website reporting the "device" is returning an error.

Your U2F device reported an error [source]

On the background, the extension is raising the following warning:

[Fido2Client] Invalid 'user.id' length: oWlwdWJsaWNLZXmmYnJwomJpZGlzZW50c[truncated] (589)

This warning is raised from this line:

https://github.com/bitwarden/clients/blob/c8f03a0d46418dc1bbe4613c10f664542fe62bd5/libs/common/src/vault/services/fido2/fido2-client.service.ts#L93

Screenshots or Videos

image

Additional Context

This report is almost a question on why there is a limit of 64 char for the userId. If it has a spec explanation, I'd be happy to report back to Sentry.

Operating System

Windows, Linux

Operating System Version

No response

Web Browser

Chrome, Firefox, Brave

Browser Version

No response

Build Version

2024.3.1

Issue Tracking Info

holow29 commented 4 months ago

WebAuthn spec specifies maximum size of 64 bytes as far as I can tell: https://w3c.github.io/webauthn/#dom-publickeycredentialuserentity-id

Greenderella commented 4 months ago

Hi there,

I am unable to reproduce this issue, it has been escalated for further investigation. If you have more information that can help us, please add it below.

Thanks!

holow29 commented 4 months ago

@LeoColomb Forgot to mention that Bitwarden handles passkeys which are FIDO2 - WebAuthn + CTAP. U2F is a different standard which WebAuthn is built upon but might not be compatible for things like this. Sentry would need to implement WebAuthn support in addition to its current U2F implementation. I don't think U2F should be expected to be stored with Bitwarden.

I am not sure if there is a way for Bitwarden to detect U2F requested and not offer to save - that might be a good change if possible.

LeoColomb commented 4 months ago

@holow29 Thanks for the additional input. As far as I can tell, Sentry "U2F" should be using FIDO2, as their API is built upon the FIDO2 Python server library.

technima commented 4 months ago

gandi.net is throwing the exact same error when I attempt to add a passkey on macOS using multiple browsers. It worked when I used my iOS device to add the passkey, but then the browser plugin says that a passkey doesn't exist when I go to sign in, even though the browser plugin says the vault item has a passkey when I search for gandi.net. The sign in workaround is to skip bitwarden and use your mobile device to scan the QR code and sign in with the bitwarden mobile app.

LeoColomb commented 4 months ago

@technima Thanks for pointing this out, I do confirm.

Gandi.net interface:

image

Bitwarden background service:

image

Error raised:

[Fido2Client] Invalid 'user.id' length: oWlwdWJsaWNLZXmnYnJwomJpZG[truncated] (465)
LeoColomb commented 4 months ago

After further investigation, it appears that in both cases, the user.id provided is actually the challenge data encoded with CBOR+base64. In both cases, the user.id in that data is the valid one.

For Sentry.io:

image

For Gandi.net:

image

LeoColomb commented 1 month ago

@Greenderella More info have been provided, but please let me know if there is anything else I can do.

helylle commented 3 weeks ago

The CBOR implementations we have tried for some projects get caught up in this same error. Compare with the CBOR implementation in this repo the user.id is copied with a new UInt8Array based on input data with offset and length. Typed Arrays created in this way are views into the original data (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#buffer)

The check on https://github.com/bitwarden/clients/blob/e3d9804b5f3364bfc375b9b5e864bd095d53ec9b/libs/common/src/platform/services/fido2/fido2-utils.ts#L4-L8 sees that the input bufferSource is not an ArrayBuffer and uses bufferSource.buffer instead which is all the input data to the CBOR decoder. This breaks user.id

LeoColomb commented 3 weeks ago

Thanks for your comment @helylle! Got three questions for you 🙂

helylle commented 3 weeks ago

Checking devtools says this function is used to decode not only user.id but also challange and id of credentials in excludeCredentials so that is something to check if they behave in the same way

helylle commented 3 weeks ago

I tested my theory with a local copy of the extension (https://contributing.bitwarden.com/) Local extension with pull request works for me with our applications and also with gandi.net as in this issue.