Bug 270553

Summary: WebAuthn excludeCredentials option stopped preventing duplicate passkey registration
Product: WebKit Reporter: nov matake <nov>
Component: New BugsAssignee: Nobody <webkit-unassigned>
Severity: Normal CC: arian.vanputten, bfulgham, earl.perez, lgarron, me, pascoe, rmondello, tim.cappalli, webkit-bug-importer, wilander
Priority: P2 Keywords: InRadar
Version: Safari 17   
Hardware: Unspecified   
OS: Unspecified   

Description nov matake 2024-03-05 18:38:07 PST
iOS 17.4 Safari (maybe Safari 17.4?) stopped preventing duplicate passkey registration even excludeCredentials option is specified.

How to reproduce
1. sign-up at https://id.moneyforward.com
2. go to https://id.moneyforward.com/webauthn/credentials and register a passkey
3. after successful registration of the 1st passkey, register 2nd passkey again on the same device

until iOS 17.3, it resulted in an error.
since iOS 17.4, it start succeeds and RP start having 2+ passkeys for the same device.
Comment 1 Radar WebKit Bug Importer 2024-03-12 19:39:11 PDT
Comment 2 arian.vanputten 2024-03-26 00:01:29 PDT
Same issue replicates on   Safari 17.4 on MacOS 14.4
Comment 3 arian.vanputten 2024-03-26 00:21:49 PDT
Note that this bug makes it extremely easy to lock yourself out of your accounts.

I just lost access to my GitHub account due to this.  (Until I find my recovery codes)

Steps to reproduce:

1. Add passkey to GitHub Account
2. Sign in with Passkey
3. Add another passkey to Github Account
   (GitHub sets excludeCredentials so that Safari shouldn't create another passkey)
4. Safari ignores excludeCredentials, throws away the old passkey and creates a new one
5. Github UI now shows two passkeys. 
6. Delete one of the two passkeys (In this case I deleted the newest one)
7. Log out
8. Try to sign in with passkey.  GitHub complains that the passkey is not known
9. Be completely locked out of your account
Comment 4 arian.vanputten 2024-03-26 04:27:14 PDT
Another (more problematic scenario) is that this an cause account lockout under adverse network conditions without the user doing anything wrong in their view:

0. have an account logging in with passkeys. with credentialId: "12345"
1. call navigator.credentials.create({excludeCredentials:["12345"]})
2. Instead of aborting due to a passkey already being stored, Safari creates a new credential "54321" and stores it in iCloud keychain, overriding "12345" in place. 
3. Network connectivity drops
4. the RP never receives the Credential from step 2. and still only has "12345" registered as an allowed Credential
4. User reloads page
5. User tries to log in with navigator.credentials.get({}).  Safari selects "54321" as that is the only passkey stored.
6. RP doesn't recognise "54321" and the user can not log in.
5. User is now permanently locked out of their account as their passkey got replaced with "54321" but the website only accepts "12345".

Either Safari should start adhering `excludeCredentials` again or it should allow  storing multiple passkeys under a single `userHandle` (though I think that is not spec-compliant).
Comment 6 Ricky Mondello 2024-04-03 08:14:06 PDT
Hi folks! This issue is resolved in Safari Technology Preview 191 and we’ll ship the fix to “blue Safari” users as soon as we can. https://webkit.org/blog/15243/release-notes-for-safari-technology-preview-191/
Comment 7 nov matake 2024-04-03 16:44:53 PDT
I've confirmed it's working as expected.