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

fix: Prevent passkey downgrades #40284

Merged
merged 2 commits into from
Apr 10, 2024
Merged

Conversation

codingllama
Copy link
Contributor

Prevent authenticators from "downgrading" passkeys to "MFA" keys by always adding passkeys to the registration credential exclude list.

Modern authenticators, like Touch ID on Chrome, will always create passkeys regardless of our registration parameters. This can lead to the following situation:

  1. User registers a passkey using Chrome and Touch ID
  2. User registers an "MFA" key using Chrome and Touch ID. The authenticator "ignores" our credential parameters and creates another passkey. Because that passkey has the same website and user as the original one, it replaces it.
  3. Teleport now thinks the user has 2 distinct keys: a passkey and an MFA key
  4. User deletes the MFA key in Teleport, which is allowed because Teleport thinks the original passkey still exists. The public key for the only existing key is removed from Teleport.
  5. User is now locked out.

This PR stops 2) from happening: the browser will error with a message in the lines of "You already registered this device".

Related to #39521.

Changelog: Prevent accidental passkey "downgrades" to MFA

web1ID := []byte{1, 1, 2} // WebAuthn / MFA
rk1ID := []byte{1, 1, 3} // WebAuthn / passwordless
dev1 := &types.MFADevice{
u2fID := []byte{1, 1, 1} // U2F
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed for clarity, nomenclature was still a bit "in flux" when I originally wrote this.

// registration.
// Letting users have both allows them to "swap" between key types in the
// same device.
if webDev := dev.GetWebauthn(); webDev != nil && webDev.ResidentKey != passwordless {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior used to be fine during the "Yubikey era", desirable even, as MFA keys don't require PINs. Yubis are still fine with this, but the recently evolved passkey behavior clearly isn't. :/

@codingllama
Copy link
Contributor Author

Friendly ping @gabrielcorado @zmb3 ?

lib/auth/webauthn/register.go Show resolved Hide resolved
@public-teleport-github-review-bot public-teleport-github-review-bot bot removed the request for review from zmb3 April 10, 2024 13:56
@codingllama codingllama enabled auto-merge April 10, 2024 14:23
@codingllama codingllama force-pushed the codingllama/passkey-downgrade branch from 52e4122 to 29346e2 Compare April 10, 2024 14:47
@codingllama codingllama added this pull request to the merge queue Apr 10, 2024
Merged via the queue into master with commit 694cd02 Apr 10, 2024
36 checks passed
@codingllama codingllama deleted the codingllama/passkey-downgrade branch April 10, 2024 15:23
@public-teleport-github-review-bot

@codingllama See the table below for backport results.

Branch Result
branch/v13 Create PR
branch/v14 Create PR
branch/v15 Create PR

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

Successfully merging this pull request may close these issues.

3 participants