WebAuthn APIs immediately abort if a conditional mediation request is open
Categories
(Core :: DOM: Web Authentication, defect, P2)
Tracking
()
People
(Reporter: eric, Assigned: jschanck)
Details
Attachments
(1 file)
|
48 bytes,
text/x-phabricator-request
|
pascalc
:
approval-mozilla-beta+
|
Details | Review |
Steps to reproduce:
I am working on integrating WebAuthn+Passkeys into a website, including conditional mediation for autofill requests.
If I start the conditional mediation credentials.get request early in the page lifecycle and then later try to start either a credentials.create or non-conditional credentials.get request (e.g. in response to a user clicking a sign in or register button), the latter is instantly rejected.
Interestingly, this is not 100% reliable; probably closer to 95% or so. I cannot find any pattern, though it's possible that there's a timeout I'm not being notified of canceling the conditional request and allowing the others to proceed.
If I disable the conditional mediation request from starting, it appears to eliminate the issue.
Pseudocode to reproduce (the site in question is in local development so I can't link it):
const onPageLoad = async () => {
try {
const conditionalResult = await navigator.credentials.get({ mediation: 'conditional', publicKey: {...}})
// use result, send to server, etc
} catch (error) {
console.log('conditional', error)
}
}
const onRegisterClick = async () => {
try {
const regResult = await navigator.credentials.create({ publicKey: {...}})
// use result, send to server, etc
} catch (error) {
console.log('register', error)
}
}
const onSignInClick = async () => {
try {
const siginInResult = await navigator.credentials.get({ publicKey: {...}})
// use result, send to server, etc
} catch (error) {
console.log('sign in', error)
}
}
onPageLoad()
<button onClick={onRegisterClick}>Register</button>
<button onClick={onSignInClick}>Sign In</button>
Actual results:
Immediately upon calling navigator.credentials.create(...) the promise is rejected with "DOMException: The operation was aborted." Same for navigator.credentials.get.
If I do NOT start the conditional mediation request (e.g. commenting out onPageLoad() in the example), both operations behave as expected.
I can reproduce this in Firefox for Mac 122, as well as Developer Edition 123.0-b4
Expected results:
The requests should start normally (and respect their configured timeouts, etc), prompting the user to create or use a webauthn credential.
This is the behavior exhibited in other browsers.
Comment 1•2 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::DOM: Web Authentication' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
| Assignee | ||
Updated•2 years ago
|
| Assignee | ||
Comment 2•2 years ago
|
||
Previously, a new webauthn request would only have priority over a pending
request if there had been a visibility change. This was an arbitrary design
decision, and was inconsequential before conditional mediation was implemented.
Comment 4•2 years ago
|
||
| bugherder | ||
| Assignee | ||
Comment 5•2 years ago
|
||
Thanks for reporting this, eric. Could you test with Firefox Nightly (2024-02-02 or later) and confirm that the new behavior matches your expectations?
Hi John,
So far, it indeed appears fixed. Visiting the same page exhibiting the issue in nightly 2024-02-02 correctly opens the prompts to create or use a passkey when a conditional request has already been opened, where it was erroring out in both the public and developer editions (same versions noted in the initial ticket)
I do not see the expected effects of conditional mediation (prompting to use an already-registered passkey when focusing the input autocomplete="username webauthn" field) but I'm unsure if that's an in-progress feature being tracked separately. Basically as if I had not started the conditional request. But it's not blocking the other operations anymore, which enables the standard flows to work.
Thanks for the rapid fix here!
| Assignee | ||
Comment 7•2 years ago
|
||
Interesting. Conditional mediation should work in that case. Do you see the autofill dropdown when you focus on the "example_username" field on https://webauthn.io?
| Assignee | ||
Comment 8•2 years ago
|
||
Comment on attachment 9377725 [details]
Bug 1877790 - give new webauthn requests priority over pending requests. r=keeler
Beta/Release Uplift Approval Request
- User impact if declined: A pending, conditionally mediated, WebAuthn request can prevent a modal request from starting.
- Is this code covered by automated tests?: Yes
- Has the fix been verified in Nightly?: Yes
- Needs manual test from QE?: No
- If yes, steps to reproduce:
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): Low risk, the feature is well covered by tests.
- String changes made/needed:
- Is Android affected?: No
I do see it on webauthn.io.
After some brief trial and error, I noticed that the input autofill was set differently: my local site had autocomplete="email username webauthn" whereas webauthn.io has autocomplete="username webauthn". When I removed email from the local autocomplete value I observed the expected behavior in FF nightly. Both sites work in Safari with the original autocomplete value.
Neither browser autocompletes if autocomplete is only set to webauthn (i.e. excluding username). Only Safari autocompletes if the tokens are reversed (autocomplete="webauthn username"), FF does not.
The closest spec reference I could find is https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens (step 4). My read is that Safari's behavior is closer to correct here and multiple autocomplete tokens should work, as should only having webauthn, but I won't pretend to be intimately familiar with how the values resolve and potentially handle conflicts.
| Assignee | ||
Comment 10•2 years ago
|
||
That's the right spec reference. There is a defined order ("tokens are the following, in the order given below") and "webauthn" must be last if it is present. The "email" and "username" tokens are both handled in step 2, so they are mutually exclusive. I'm not sure why autocomplete="webauthn" is not working for you. We have a test that exercises that case, and I believe Safari supports it as well. But please open another bug if you find a case where you think we should be showing the dropdown.
| Reporter | ||
Comment 11•2 years ago
|
||
Thanks for clarifying. So it sounds like as long as webauthn is at the end of the autocomplete token list, the dropdown should be displayed, regardless of whether other tokens come first (or which token(s) precede it). I'll continue doing some local testing and potentially follow up with a separate report.
In any case, thanks again for looking into this and the quick fix!
Comment 12•2 years ago
|
||
Comment on attachment 9377725 [details]
Bug 1877790 - give new webauthn requests priority over pending requests. r=keeler
Approved for 123 beta 8, thanks.
Comment 13•2 years ago
|
||
| uplift | ||
Comment 14•2 years ago
|
||
| bugherder uplift | ||
Description
•