WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
311099
[WebAuthn] PRF extension returns encrypted hmac-secret output for CTAP2 security keys (missing decryption step)
https://bugs.webkit.org/show_bug.cgi?id=311099
Summary
[WebAuthn] PRF extension returns encrypted hmac-secret output for CTAP2 secur...
Berni
Reported
2026-03-30 05:16:18 PDT
SUMMARY When using the PRF extension with CTAP2 security keys (USB/NFC), Safari returns the AES-256-CBC encrypted hmac-secret output directly as PRF results without decrypting it. Platform authenticators (Touch ID, Face ID via ASAuthorization) are unaffected. STEPS TO REPRODUCE 1. Register a credential with PRF extension using a FIDO2 security key (e.g. YubiKey) on Safari 2. Authenticate with the same credential and salt on Safari 3. Authenticate with the same credential and salt on Chrome 4. Compare derived keys or encrypt/decrypt across browsers Test page:
https://b-straub.github.io/BlazorPRF/
EXPECTED PRF output matches across browsers for the same credential + salt (deterministic, per spec). Cross-browser encryption/decryption works. ACTUAL - Safari macOS <-> Safari iPadOS: PRF outputs match (both apply the same code path, producing identical but still encrypted values) - Safari <-> Chrome: PRF outputs differ (Chrome correctly decrypts the hmac-secret response) - Cross-browser encryption/decryption fails ROOT CAUSE In DeviceResponseConverter.cpp, parseAuthenticatorDataExtensions() takes the raw hmac-secret byte string from the CTAP2 response and directly creates ArrayBuffers without decrypting: } else if (hmacIt->second.isByteString()) { auto& hmacOutput = hmacIt->second.getByteString(); // BUG: hmacOutput is still AES-256-CBC encrypted! RefPtr<ArrayBuffer> first = ArrayBuffer::tryCreate( hmacOutput.span().first(std::min<size_t>(32, hmacOutput.size()))); outputs.prf = AuthenticationExtensionsClientOutputs::PRFOutputs { }; outputs.prf->results = AuthenticationExtensionsClientOutputs::PRFValues { first, second }; } The decryption logic already exists in HmacSecretResponse::parse() (Pin.cpp), which correctly calls decryptForProtocol(). However, it is never invoked in the response processing pipeline. CtapAuthenticator (CtapAuthenticator.cpp) stores the shared key in m_hmacSecretRequest but never uses it to decrypt the hmac-secret response. SUGGESTED FIX Either: 1. readCTAPGetAssertionResponse() accepts the shared key and calls HmacSecretResponse::parse() to decrypt before constructing PRF output, or 2. CtapAuthenticator post-processes the response using its stored m_hmacSecretRequest to decrypt the extension output WHY SAFARI-TO-SAFARI APPEARS CONSISTENT Safari produces deterministic (but wrong) PRF output because the platform key agreement results in the same shared secret across sessions. Both macOS and iPadOS run the same WebKit code path, so both return identical encrypted values. This gives false confidence that cross-device PRF works, when in fact the values are not interoperable with any correctly implementing browser. ENVIRONMENT - Safari 26.4 on macOS Tahoe / iPadOS - FIDO2 security key (YubiKey) via CTAP2/HID - Platform authenticators (ASAuthorization path) are NOT affected RELATED - PR #53734 (original PRF implementation):
https://github.com/WebKit/WebKit/pull/53734
- Review comment by @joostd:
https://github.com/WebKit/WebKit/pull/53734#pullrequestreview-4020705594
Attachments
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2026-04-06 05:17:11 PDT
<
rdar://problem/174154188
>
Joost van Dijk
Comment 2
2026-04-08 08:10:17 PDT
It seems this has already been fixed in branch WebKit-7624.1.16.13.
https://github.com/WebKit/WebKit/tree/WebKit-7624.1.16.13.2/
In particular, here:
https://github.com/WebKit/WebKit/blob/dd80a9e46546e49c4a5da9115458077a51220f49/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp#L151
Any idea when we can expect a fix to land in Safari?
Joost van Dijk
Comment 3
2026-04-09 05:13:10 PDT
(In reply to Joost van Dijk from
comment #2
)
> It seems this has already been fixed in branch WebKit-7624.1.16.13. >
https://github.com/WebKit/WebKit/tree/WebKit-7624.1.16.13.2/
> In particular, here: >
https://github.com/WebKit/WebKit/blob/
> dd80a9e46546e49c4a5da9115458077a51220f49/Source/WebCore/Modules/webauthn/ > fido/DeviceResponseConverter.cpp#L151 > > Any idea when we can expect a fix to land in Safari?
Great! I see it has landed in Safari Technology Preview Release 241 (WebKit 21625.1.12)
Berni
Comment 4
2026-04-09 07:36:56 PDT
Confirmed to be fixed in Safari TP 241. Safari-Chrome roundtrip with FIDO key is working.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug