Repository navigation
Handle WebAuthn assertions without user handles - #9060
Conversation
|
Warning Review limit reachedNext included review available in 5 minutes. View limit detailsLimit details: You’ve used all 10 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughWebAuthn assertion replies now accept optional user handles and omit the ChangesWebAuthn assertion reply handling
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 25✅ Passed checks (25 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Sources/Panels/BrowserWebAuthnSupport.swift`:
- Around line 656-686: Move the static assertion-building behavior from
BrowserWebAuthnCredentialReply onto the existing WebAuthn coordinator or a
constructable builder/value owner. Update callers to use that owner, preserve
the current assertion response structure, and remove the static-only
BrowserWebAuthnCredentialReply namespace.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d72664fd-f7b9-4d3b-81f1-277585ac068c
📒 Files selected for processing (2)
Sources/Panels/BrowserWebAuthnSupport.swiftcmuxTests/BrowserWebContentProcessTests.swift
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cmuxTests/BrowserWebContentProcessTests.swift (1)
194-210: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover the empty-handle branch too.
The helper treats both
niland emptyDataas absent, but this test exercises onlynil. Add a second case withuserHandle: Data()to prevent regressions in the other newly supported path.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cmuxTests/BrowserWebContentProcessTests.swift` around lines 194 - 210, Extend webAuthnAssertionReplyOmitsAbsentUserHandle to also call assertionReply with userHandle: Data() and verify the resulting response omits userHandle, preserving the existing nil case and assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@cmuxTests/BrowserWebContentProcessTests.swift`:
- Around line 194-210: Extend webAuthnAssertionReplyOmitsAbsentUserHandle to
also call assertionReply with userHandle: Data() and verify the resulting
response omits userHandle, preserving the existing nil case and assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3187cd22-e6cd-453a-b4ab-b5e1f4fef7b9
📒 Files selected for processing (2)
Sources/Panels/BrowserWebAuthnSupport.swiftcmuxTests/BrowserWebContentProcessTests.swift
|
All contributors have signed the CLA ✍️ ✅ |
|
Thank you for this, @marius-jacobs! No more crash when a YubiKey finishes passkey sign-in without a user handle is a great fix. It's reviewed, up to date with main and CI is running. The one thing left before we can merge is the CLA: just comment the line below and we'll land it :D
|
|
Thanks! I have read the CLA Document v2.2 and I hereby sign the CLA. |
|
Thank you @marius-jacobs! So close :D The bot only counts a comment that is exactly this line on its own (no extra text or trailing period):
|
|
I have read the CLA Document v2.2 and I hereby sign the CLA |
|
Merged, thank you @marius-jacobs! No more crash when a YubiKey finishes passkey sign-in without a user handle :D |
|
Merge receipt for |
74b3778 test: restore manaflow-ai#14406's sidebar AX walk assertion lost in the manaflow-ai#14408 squash (manaflow-ai#14593) 3b14475 ci: run swift-package-tests on owned minis when the run builds no Release helper (manaflow-ai#14411) 2a40caa Handle WebAuthn assertions without user handles (manaflow-ai#9060) 6cdb469 Match upload rules on HostName when a broker rewrites the host (manaflow-ai#11477) 265bef2 fix: hide browser affordances while the browser is disabled (manaflow-ai#10866) (manaflow-ai#13023) 99c4404 ci: ignore a GitHub API error in the stale-run check (manaflow-ai#14603) ceae537 test(cloud): bind the first workspace receipt before discovery (manaflow-ai#14618) # Conflicts: # .github/workflows/ci-macos.yml # .github/workflows/ci.yml # .github/workflows/remote-daemon.yml
…ey test RP plans/cmux-next/passkeys.md proposes Chrome-parity passkeys for CEF and WebKit panes. Its "Known bugs: do not repeat" table lists every passkey bug in the old app and repo history (K1-K18) with symptom, root cause, fix status and the regression test each engine needs. New findings: cmux next lost the whole WebKit passkey bridge with the legacy deletion on 2026-09-29 (#15659), so WebKit panes are back to "partial passkey support" and the #9060/#15525 fixes are gone; the RC channel ships without the passkey entitlement (verified on the installed 0.65.0-rc); three fixes on main never merged (#6766 hybrid routing, #8630 private-selector crash, #9529 leaked presentation windows); the bridge was silently dropped for ten weeks by cb1a6de; the bridge ignores AbortSignal; Chromium refuses WebAuthn in a tab that is not VISIBLE (cmux-browser #95), which applies to our CEF occlusion and hibernation. tests/passkeys: a local relying party (index.html, frame.html on frame.localhost for cross-origin iframes, scenarios.js) and run.mjs, which runs 17 scenarios in Chromium with a DevTools virtual authenticator. Stock Chrome for Testing 153.0.8010.12 passes 17/17 (16 judged, 1 record-only); the same runner targets a cmux CEF instance with --cdp, and --serve serves the page for manual runs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Summary
response.userHandlewhen the authenticator does not provide oneRoot cause
ASAuthorizationPublicKeyCredentialAssertion.userIDis imported into Swift asan implicitly unwrapped optional. Hardware security keys can legitimately return
no user handle for non-discoverable credentials, including assertions selected
from an
allowCredentialslist.cmux passed that value into a non-optional
Dataparameter, which forced anunwrap and trapped on the main thread after AuthenticationServices completed a
YubiKey assertion.
This behavior is permitted by the WebAuthn specification:
https://www.w3.org/TR/webauthn-3/#dom-authenticatorassertionresponse-userhandle
Impact
YubiKey and other hardware-key authentication can complete without crashing
when the assertion has no user handle. Assertions that include a user handle
retain their existing serialized response.
Validation
74c7abd7preserves the pre-fix nil trap0cf6468dpasses the nil fixture by omittinguserHandleswiftc -frontend -parsepasses for both changed Swift filesscripts/check-pbxproj.shpassesscripts/lint-pbxproj-test-wiring.shpassesCommand Line Tools rather than full Xcode; upstream's main CI workflow is
currently paused for pull requests
Related to #1278 and the WebAuthn implementation from #2727.
Summary by CodeRabbit
userHandlefield when no (or an empty) user handle is available.userHandlewhen it is absent, including checks for the resultingid,signature, and response payload.