CVE-2026-43795
Overview
Background
- CBOR
- Concise Binary Object Representation, the binary map/array format WebAuthn uses for authenticator data and extension outputs.
- credProps extension
- A WebAuthn client extension whose output is a map that may contain a boolean ‘rk’ (resident key) flag.
- Iterator container mismatch
- Comparing or dereferencing an iterator against a different container’s end() is undefined behavior and can read invalid memory.
Root Cause Analysis
This fixes a logic error — comparing and dereferencing a hash-map iterator against the wrong container — in WebAuthn CBOR parsing. AuthenticationExtensionsClientOutputs::fromCBOR decodes the top-level CBOR map (decodedMap), finds the ‘credProps’ entry, and then tried to look up the nested ‘rk’ key by REUSING the same iterator variable: it = it->second.getMap().find(cbor::CBORValue(“rk”)), then tested if (it != decodedMap.end() && it->second.isBool()). The find() runs on the nested credProps submap and returns an iterator into THAT submap, but the code compared it against decodedMap.end() — the end of the OUTER map — and reassigned the outer iterator in the process. Comparing iterators from two different containers is undefined behavior, and when ‘rk’ is absent from credProps the submap’s find() returns the submap’s end iterator; testing it against the wrong end and then dereferencing it->second reads past/into an invalid iterator, causing an out-of-bounds read / crash.
The fix takes a stable reference to the nested map (const auto& credPropsMap = it->second.getMap()), searches it with a separate iterator (credPropsIt), and compares against credPropsMap.end() before reading credPropsIt->second.
The restored invariant is that an iterator is only compared and dereferenced against its own container. The regression test decodes {“credProps”: {}} (credProps present, no ‘rk’) and expects a valid result with credProps->rk false.
Attack Path
- Return a crafted assertion A malicious authenticator/site supplies a WebAuthn response whose CBOR client-extension outputs contain a credProps map with no ‘rk’ key.
- Parse the extension outputs WebKit calls AuthenticationExtensionsClientOutputs::fromCBOR, which searches the credProps submap for ‘rk’.
- Compare against the wrong end The submap’s end iterator is compared to the outer map’s end (undefined behavior) and then dereferenced.
- Crash / OOB read Dereferencing the invalid iterator reads out of bounds, crashing the WebContent process.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
AuthenticationExtensionsClientOutputs::fromCBORSource/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.cpp |
modified | Searches the nested credProps map with its own iterator (credPropsIt) compared against credPropsMap.end(), instead of reusing the outer iterator and comparing to decodedMap.end(). |
CBORReaderTest.AuthExtensionsFromCBOR_CredPropsWithoutRkTools/TestWebKitAPI/Tests/WebCore/CBORReaderTest.cpp |
added | Regression test decoding {"credProps":{}} to ensure a missing 'rk' key no longer misuses the iterator. |
Files Changed
Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientOutputs.cppTools/TestWebKitAPI/Tests/WebCore/CBORReaderTest.cpp
Audit Directions
- Same file: nested map lookupsAudit AuthenticationExtensionsClientOutputs and nearby WebAuthn CBOR parsers for find() results compared to a different map’s end() or reused iterator variables across nested maps.
- CBOR getMap()/find patternsGrep for getMap().find(…) followed by comparison to an outer .end(); ensure each comparison uses the same map the find() ran on.