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

User Verification PIN implementation is not compliant with FIDO specs #9672

Open
1 task done
bwbug opened this issue Jun 15, 2024 · 2 comments
Open
1 task done

User Verification PIN implementation is not compliant with FIDO specs #9672

bwbug opened this issue Jun 15, 2024 · 2 comments
Labels
browser Browser Extension bug

Comments

@bwbug
Copy link

bwbug commented Jun 15, 2024

Steps To Reproduce

Register a passkey at passkeys.io and store it in your Bitwarden browser extension, then perform the following tests (sign out after each successful login):

  1. Set an arbitrary vault unlock PIN, then start a stopwatch when clicking the "Sign in with a passkey" button on passkeys.io. Confirm the passkey to be used, enter the PIN at the prompt — but do not click Submit or hit Enter. When the stopwatch indicates that the elapsed time is in the range 31–59 seconds, click Submit.
  2. Set an arbitrary vault unlock PIN, then click the "Sign in with a passkey" button on passkeys.io, and confirm the passkey to be used. Deliberately enter and submit an incorrect PIN; repeat as many times as possible before the 60-second timeout (in my tests, I achieved approximately 25 consecutive submissions of incorrect PINs). Now repeat the passkey login (by clicking the "Sign in with a passkey" button again), this time entering the correct user verification PIN.
  3. Set a vault unlock PIN that consists of a single character (e.g., 0). Use the "Sign in with a passkey" option on passkeys.io, and enter the PIN when prompted for user verification.
  4. Set a vault unlock PIN that consists of more than 64 characters (my tests reached PIN lengths up to 5,279 characters). Use the "Sign in with a passkey" option on passkeys.io, and enter the PIN when prompted for user verification.

Expected Result

Per the FIDO CTAP specifications, the following authenticator behaviors are mandated. Here, I am referencing the 21 June 2022 Proposed Standard, so there may be a more relevant document for standards currently in force; however, I believe that any differences do not significantly affect the issues raised in this report.

Expected Test Results:

  1. The authenticator should time out if the user verification has not been completed within 30 seconds (6.5.2.1).
  2. If the number of incorrect PIN retries is greater than 8, then the authenticator's user verification PIN should be disabled, requiring the entire authenticator to be reset (6.5.2.2).
  3. Authenticators should not allow user verification PINs shorter than 4 Unicode characters (6.5.1).
  4. Authenticators should not allow user verification PINs longer than 63 bytes (6.5.1).

Actual Result

Testing indicates that none of the above specifications are met. The actual test results are:

  1. The user verification PIN is accepted for up to 60 seconds (from the time that "Sign in with a passkey" is clicked), resulting in a successful passkey login.
  2. After submitting more than 8 incorrect retries of the user verification PIN, the PIN still works for logging in with a passkey. The PIN is not disabled, and there is no sign that the authenticator has been "reset".
  3. User verification PINs shorter than 4 characters can be successfully used for passkey login.
  4. User verification PINs much longer than 63 bytes can be successfully used for passkey login.

Screenshots or Videos

No response

Additional Context

The underlying issue is that the requirements for the CTAP user verification PIN are fundamentally different from the requirements for the Bitwarden vault unlock PIN (or the Bitwarden master password). Therefore, using the vault unlock PIN or the master password for CTAP user verification is a flawed design. A separate PIN should be used for passkey user verification; ideally, an encrypted version of this UV PIN (or its hash) should be stored in the vault and syncable, so that the same passkey PIN can be used across all devices.

Operating System

Windows

Operating System Version

No response

Web Browser

Chrome

Browser Version

No response

Build Version

2024.6.0

Issue Tracking Info

  • 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.
@bwbug bwbug added browser Browser Extension bug labels Jun 15, 2024
@coroiu
Copy link
Contributor

coroiu commented Jun 25, 2024

Hello and thank you very much for your report. I just want to start out by saying that User verification for Passkeys in Bitwarden is a feature that is still being developed. This is the first version of the PIN implementation and it will continue to improve over time!

That said, the main reason we do not currently meet these requirements is that Bitwarden does not currently implement CTAP2. We implement the Web Authentication API (WebAuthn) which implies a specific abstract functional model for a WebAuthn Authenticator, and [FIDO-CTAP] is "only" one example of a concrete instantiation of this model. We currently only claim full support for WebAuthn L2, i.e. all deviations from L2 are considered bugs, while a deviation from L3 might be an unimplemented feature. That said we do support features from newer versions.

Looking ahead
We are working on a CTAP2 compatible implementation on the mobile side, which will eventually be ported over to the web clients.

We are also still exploring the best way to implement a PIN, from both a security and usability perspective. So exactly how it will end up looking, i.e. separate or not separate from unlock PIN, synced or not synced, I cannot say yet.

@bwbug
Copy link
Author

bwbug commented Jun 25, 2024

@coroiu Thank you for your response, and for explaining the current status of Bitwarden's standards compliance.

So exactly how it will end up looking, i.e. separate or not separate from unlock PIN

If you have not already done so, I would recommend that you follow the discussion in this feature request thread on the Community Forum:

Passkey User Verification Independent of Vault Unlock Method

Linking the UV PIN to the vault PIN will invariably create many unintended problems, because the two PINs serve completely different purposes, and have different threat models. By making the two PINs distinct entities, a user would still have the option of re-using their vault PIN as their UV PIN, if they prefer no to memorize an additional PIN (this could even be the default UV PIN value, as long as users are able to overwrite it with a distinct UV PIN value that is different from their vault unlock PIN).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
browser Browser Extension bug
Projects
None yet
Development

No branches or pull requests

2 participants