NEW 273712
WebAuthn/passkeys intermittently stop functioning (hangs or doesn't resolve promise)
https://bugs.webkit.org/show_bug.cgi?id=273712
Summary WebAuthn/passkeys intermittently stop functioning (hangs or doesn't resolve p...
Eric S
Reported 2024-05-03 14:37:57 PDT
Calls to `navigator.credentials.get` appear to have intermittently started either no-op'ing or never resolve the promise, both of which leave a user hanging in a lurch. Sometimes the WebAuthn dialog opens (and does nothing if the user presses continue), and sometimes it does not open at all. When it does open, frequently nothing happens at all when pressing continue. Similar behavior for the conditional mediation/autofill UI. This results in completely broken sign-in and registration flows using passkeys (as well as non-passkey WebAuthn). The same pages work fine in other browsers with no other changes, so I'm very confident it's not an issue with the logic on the website (also, it worked fine in Safari last week and nothing has changed) By adding debug statements, breakpoints, etc, I can see the code is executing fine right up until the `.get()` call (similar behavior on `.create()` frequently) and then... nothing. I've tried: - Changing from async/await to promises (.then().catch()) - Changing various options passed to the API - Adding and removing AbortSignals (maybe this is related to https://bugs.webkit.org/show_bug.cgi?id=271257) - Checking on `localhost` projects and real-world websites (my own and others) And more. I've experienced this on: - macOS 14.4.1 / Safari Version 17.4.1 (19618.1.15.11.14). Desktop and laptop, various M-series chips, with and without biometric hardware - Safari technical preview Release 193 (Safari 17.4, WebKit 19619.1.9.4) - iOS/iPadOS 17.5 beta (b3?) iOS seems to work more often/more consistently, iPadOS less often, and desktop is now quite rare when it does work. I've been having intermittent issues (including https://bugs.webkit.org/show_bug.cgi?id=271747) that started, I think, earlier this week. I also filed this under FB13773774 (navigator.credentials.create (and get) promise does not always resolve after user tries to register or sign in with a passkey) which contains a screen recording and sysdiagnose reports. Note that when `.create()` does actually dismiss the modal dialog (through continue, not cancel) but experiences this issue, it seems that the passkey is saved to the system keychain but the website never gets the response and consequently is unable to store anything their end to finish the webauthn processing. This leads to EXTREMELY confusing interactions later on, since the user can be prompted to sign in with their passkey that's not actually registered with the relying party. On iPad (only?) I noticed an EXTREMELY brief (a frame or two) error flash in the touchID prompt - I think indicating the fingerprint failed? I haven't seen anything equivalent on other platforms. Happy to provide any additional information, debug statements, jump on a screen sharing session, etc. Whatever can help!
Attachments
Conditional mediation prompted for wrong domain (1.16 MB, image/png)
2024-10-16 11:25 PDT, Eric S
no flags
Kostas
Comment 1 2024-05-05 01:41:38 PDT
Probably due to removal of user gesture requirements and introduction of rate-limiting in 17.4 (https://forums.developer.apple.com/forums/thread/747036). "Instead of a per-page freebie/keeping track of user gestures and cancel events/etc., there's a new rate limiting mechanism with a progressive backoff if too many requests come in close together." But not sure this happens in webkit or authenticator level.
arian.vanputten
Comment 2 2024-05-05 01:53:27 PDT
I've been running into this a lot during development and it's very frustrating. Often I can fix it by killing AuthenticationServices in Activity Manager. Create calls seem to ramp up the rate limit faster than get calls in my experience. Also it seems conditional mediated calls are exempt from the rate limit. My suggestion would be to have the rate limit abort the Promise instead of letting it hang forever. I've experienced that the limit also seems global. If I hit the rate limit on localhost then sign in gets broken on other websites.
Eric S
Comment 3 2024-05-05 09:05:46 PDT
The inconsistency I've run into feels like it could be related to some sort of rate-limiting, though the pages in question are following all of the traditional guidelines for reacting to user gestures so I can't think of any reason that they'd actually hit any sort of rate limiting. I suppose it depends hugely on implementation details. > But not sure this happens in webkit or authenticator level. I get the system passkey prompt just fine in Firefox (and the promise resolves properly), which suggests to me that if this _is_ a rate-limiting issue, it's specific to Safari/Webkit rather than the system-wide. YubiKeys are similar impacted when the dialog doesn't even open and they're completely stateless devices, so I can't intuitively figure out how such a thing would even be implemented on the authenticator itself. > I've been running into this a lot during development and it's very frustrating. Often I can fix it by killing AuthenticationServices in Activity Manager. Thanks for this hint! Just tried this - it seems to help the webauthn dialog show more consistently, but I'm still observing the promise hanging when clicking Continue in the dialog. As an extra data point on timing, two requests more than 12 hours apart (overnight) both stalled in an equivalent way.
Radar WebKit Bug Importer
Comment 4 2024-05-10 14:38:15 PDT
Ahmad Saleem
Comment 5 2024-05-13 05:59:08 PDT
@Eric & Others - appreciate if you can confirm whether it is recent user experience with 17.4 onward (like recent regression) or it is consistently since past few release and use to work in iOS 16?
Kostas
Comment 6 2024-05-13 06:55:36 PDT
My current feeling is this started with 17.4.
Eric S
Comment 7 2024-05-13 09:18:19 PDT
@Ahmad Definitely a recent regression in my experience, though I don't have easy access to older devices for more testing. I first ran into it on macOS 14.4 about two weeks ago and started seeing it about a day later on iOS 17.4 and the 17.5 betas.
stephen
Comment 8 2024-06-22 11:20:52 PDT
(In reply to Ahmad Saleem from comment #5) > @Eric & Others - appreciate if you can confirm whether it is recent user > experience with 17.4 onward (like recent regression) or it is consistently > since past few release and use to work in iOS 16? Not to pile on with a +1 comment, but I also started noticing this (both myself and reports from customers) roughly starting in mid-April on a website that's had a passkey implementation that's worked fine since early 2023.
pascoe@apple.com
Comment 9 2024-06-26 14:09:28 PDT
Has anybody experiencing this behavior has tried the iOS/iPadOS 17.6 beta or macOS 14.6 beta and seen if it still happens? There was a fix for a similar area, but I'm not sure it's the exact behavior described here. Thank you.
Eric S
Comment 10 2024-07-01 18:01:55 PDT
@pascoe - I don't currently have access to a macOS system running the 14.6 beta. My iPhone is on the 18 beta and I haven't hit it there (not sure if that's relevant to 17.6), but I experience the issue _vastly_ more often on localhost than on non-local environments, which is not really something I can test from a phone. I can look into adding the desktop beta in a dual-boot setup, but it will take a little while to get it set up (on top of the US holiday this week)
stephen
Comment 11 2024-07-01 23:45:55 PDT
(In reply to pascoe@apple.com from comment #9) > Has anybody experiencing this behavior has tried the iOS/iPadOS 17.6 beta or > macOS 14.6 beta and seen if it still happens? > > There was a fix for a similar area, but I'm not sure it's the exact behavior > described here. Thank you. Today I upgraded to macOS 14.6 beta with Safari 17.6 and I'm still able to repro the issue within 5 minutes of repeatedly attempting to use passkey auth in incognito windows.
Eric S
Comment 12 2024-07-31 14:38:08 PDT
I just installed Safari Technical Preview 200 (Release 200 (Safari 18.0, WebKit 19620.1.1)) and the issue persists.
Kostas
Comment 13 2024-10-01 06:33:31 PDT
We seem to be running continuously into this when creating the first implementations of conditional passkey creation. I guess the attempts add up. First, the promises hang, and later on, sometimes much later, they resolve but at some point the operations immediately return a NotAllowed error (probably when enough are "stacked" in the rate-limit).
Eric S
Comment 14 2024-10-16 11:22:13 PDT
This appears to be getting progressively worse with time on macOS desktop (I'm now on Sequoia 15.0.1 and Safari 18.0.1): even immediately after restarting my computer, I'm experiencing the same issue on (AFAIK; lots of tabs open) the _very first_ WebAuthn request - even on real websites, not just localhost. The same page works fine in e.g. Firefox which is able to display the system passkey dialog for modal requests, and the user selection process for conditional requests. So it seems to be a Safari-specific issue, not the system-level services. What I've also noticed is that, on rare occasion, I've been given the conditional mediation passkey selection in completely inappropriate contexts: for the WRONG SITE and on a domain on which I do not have passkeys nor, to my knowledge, has webauthn support at all. I can't reliably reproduce it, but I'll attach a screenshot. My (completely unfounded) hunch is that incomplete requests hang past a page's lifetime and gum up everything. I intend to test manually aborting any pending requests `beforeunload` in my own implementation, but at this point everything is so gummed up that I probably can't do any reliable testing. However, at the same time, I seem to no longer have the issue on iOS (18.1 DB7) - so that's nice.
Eric S
Comment 15 2024-10-16 11:25:14 PDT
Created attachment 472957 [details] Conditional mediation prompted for wrong domain Note that I'm being shown a list of passkeys for localhost, despite not being on that domain. The input field in question (as of writing, I'm not sure if this is true as of the screenshot) has `autocomplete=none` and the site does not, to my knowledge, support WebAuthn at all (I certainly have never used it there). The list of passkeys for localhost is correct in the context of localhost, but obviously they should not be shown on this domain.
Kostas
Comment 16 2024-10-17 03:31:25 PDT
(In reply to Eric S from comment #14) > My (completely unfounded) hunch is that incomplete requests hang past a > page's lifetime and gum up everything. I have exactly the same (completely unfounded) hunch.
Note You need to log in before you can comment on or make changes to this bug.