[6] [WebCore] Fix UAF in Range::createContextualFragment via Trusted Types policy callback
Rated High because the diff promotes raw Node/Element captures to Ref/RefPtr across the Trusted Types createHTML callback in Range::createContextualFragment; without promotion, attacker-controlled JS in the policy callback can drop all references and force GC, then post-callback dereference operates on freed memory.
Captured Node/Element references in Range::createContextualFragment become Ref/RefPtr, pinning lifetime across the Trusted Types policy invocation.
Source/WebCore/dom/Range.cpp
Re-entrancy UAF: a raw Node pointer is captured before invoking a Trusted Types policy callback that runs attacker JavaScript synchronously, then dereferenced after.
Patch Details
The function's local captures for context node and start container become reference-counted. The policy callback is unchanged.
Background
Range::createContextualFragment parses an HTML fragment in the context of the Range's start container. Trusted Types' createHTML policy sits on the input string path, sanitizing the supplied HTML by running a user-installed JavaScript callback before parsing.
Analysis
Pre-fix, the function extracted a raw Node*/Element* from the Range's boundary and continued using it across the createHTML call. That callback is attacker-controlled JS. It can mutate the Range (e.g., range.setEnd(document, 0) — setEnd collapses start to end on order inversion per the visible implementation), drop all other live references, and force GC.
When control returns from createHTML, the cached raw pointer references a destroyed Node. Subsequent parsing context lookup, fragment construction, or attach operates on freed memory. Promoting the captures to Ref/RefPtr keeps the Node alive for the duration of the stack frame, restoring the invariant.
This weakens the DOM lifetime invariant across JS re-entrancy points. The exploit primitive is UAF on a DOM Node reachable from script.
Audit directions
- DOM functions that invoke user-controllable callbacks (Trusted Types policies, MutationObservers, custom-element callbacks,
requestIdleCallback) while holding raw Node/Element pointers. Grep for.get()immediately followed by a known callback dispatch site. - Other Range mutators that re-enter JS.
Range::extractContents,Range::cloneContents, andRange::deleteContentscross MutationObserver and DOM-level event boundaries. HTMLFragmentParsercallers that capture a context node and re-enter script during parsing.