[4] Document.open() UAF via MutationObserver on Cross-Document Element
Severity: High | Component: WebCore DOM | 6767475
Rated High because the observable effect is an ASAN segfault in firstDOMWindow during document.write — a crash consistent with use-after-free or null dereference on the document's DOMWindow association — and the trigger is fully reachable from web content via MutationObserver. The actual fix was in a separate commit (300757@main, later reverted in 300886@main); this commit adds only the regression test, limiting diff-backed analysis of the fix mechanism.
Patch Details
This commit adds only a regression test — no production code change is included. The test creates an element from a DOMParser-parsed document, attaches a MutationObserver that calls document.open() on the main document, then triggers the observer by setting an attribute. The actual fix was landed in commit 300757@main and later reverted in 300886@main.
LayoutTests/fast/dom/Document/open-triggered-by-mutation-observer-on-element-from-a-parsed-doc-crash.html
+ const element = (new DOMParser()).parseFromString("<!DOCTYPE html><p>foo</p>","text/html").documentElement;
+ (new MutationObserver(_ => document.open())).observe(element, {attributes: true});
+ element.setAttribute("class", "bar");
+ document.body.innerHTML = "PASS if no crash.";
Re-entrant document.open() via MutationObserver on a cross-document element invalidates the calling document's DOMWindow association mid-execution.
Background
MutationObserver is a DOM API that delivers notifications when observed DOM nodes are mutated. Observers fire callbacks in JavaScript during microtask checkpoints. document.open() clears the current document and prepares it for writing — this operation can tear down and reinitialize document state including its association with the browsing context's DOMWindow. DOMParser creates a new Document from markup without an associated browsing context — elements from such documents have no live frame or window, but they can still be observed by MutationObserver instances belonging to any document.
Analysis
The test case reveals the trigger: calling document.open() from within a MutationObserver callback that fires on an element belonging to a different document (one created by DOMParser). The crash occurs in WebCore::firstDOMWindow called from jsDocumentPrototypeFunction_write, indicating that during document.open() in this context, the document's association with its browsing context or DOMWindow becomes invalid. The element being observed belongs to a parser-created document with no browsing context, and the mutation observer callback executes document.open() on the main document during attribute mutation delivery, likely invalidating state that the call stack still references.
Aaa Aaaaaaaa Aaaaa Aaaaa a Aaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a Aa Aaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaa Aaaaaaa Aaaa Aa Aaaaaaaaaaaaa Aaa Aaaaaaaaaa Aaaaaaaaaaa Aaaaa a Aaaaaaa Aaaaa Aaaaa Aaaaaaa Aaa Aaa Aaaaaaaaaaa Aa Aa Aaaaaa Aa a Aaaaaaaa Aaaaaaaaaaaa Aaaaaaaaa Aa Aaaaaaaa Aaaaa Aaaaa Aaa Aaaaa Aaaaaaa Aaaa Aaa Aaaa Aaaaa
Aaaaa
Aaaaa Aa a Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Aaa Aaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaa Aaaaaaa
Aaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaa
Aaa
Aa Aaa Aaaaaaaaaa Aaaaa Aa a Aaaaaaaaaaaaaa Aa Aaa Aaaaaaaaaaa Aaaaaa Aaaaaa Aaaa a Aaaaaa Aaaa Aaaaaaaaaaaa Aa Aaaaaaaa Aaaaa Aaaaaaaaaaa Aaaa Aaaa Aaaaaaaaa Aa Aaa Aaaaaaaaaa Aaaaaaa Aa Aaaaaaaaaaa Aaa Aaaaaa Aaaaaa Aa Aaa Aaaaa Aaaaaaaa Aaaaaaaa Aaa Aaaa Aaaaaaaa Aa Aaa Aaa Aaaaa Aaaaaaaa Aaaaaa Aaaaaa Aa Aaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaaaa Aaaaaaa Aaaaaa Aaaaaaa Aaa Aaaaaaaaaaaaaaaaa Aaaaa Aaaaaaaaa Aaaa Aaa Aaaaaaa Aaa Aaaaaaaaaaaaaaaaaa Aa a Aaaaaaaaaaaaaaaaaaa Aaaaaaaa Aaa Aaaaaaa a Aaaaaaaaaaaa Aaaaa Aa Aaaaaaaaaaaaaaaaa Aa Aaaaaaaa Aaaa Aaaaaaaa Aaaaaaa Aaa Aaaaaaaaa Aa Aaa Aaaaaaaaaa Aaaaa Aa a Aaaaaaaaaaaaaaa Aaaaaaaaaaaa Aaa Aaaa Aaaaaaaaa Aaaaaa Aaa Aaaaaaaa Aaaaaaa Aa Aaaaaaaaaa
Aaaaaaaaaaaaaaaaa Aa a Aaaaaaaaa Aaaaaa Aa Aaaaaaaa Aaaa Aa Aaaaaa Aaaaaaa Aa Aaaaaaaa Aaaaaaa Aaaaaaaa Aaaaaaaaa Aaaaaaa Aaaaa Aaaaa Aaaaaaaa Aaaa Aaaaaaaaa Aa Aaaaaaaa Aaaaaaaaa Aaaaaaaaaa Aaaa Aaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaa Aaaaaaaaaaa Aa Aaaaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaa Aaaaaaaaaaa Aa a Aaaaaaa Aaaa Aaaaaa Aaa Aaaaaaaaaa Aaaaaaaaaa Aaaaaaaaa
Aaaaaaaaa Aaa Aaaaaa Aaa Aaaa Aa Aaa Aaaaaaaa Aa Aaaa Aaaa Aaa Aaa Aa Aaaaaa Aaaaaaaaaaaaa Aaa Aaaaa Aaaaaaaaa Aaa Aaaaaaa Aaa Aaaaaaaa Aaaa Aaa Aaaa Aaaa Aaa Aaa Aaaaaa Aaa Aaaa Aaaaaaa Aaaa Aa Aaaaaaaaaaaa Aaaaaaaaa Aa Aaa Aaaaaaaaaa Aaaaa
🔒Explores the document lifecycle and memory model implications of this crash, and whether it could escalate beyond denial-of-service
Subscribe to read more
Audit directions
a Aaaaaaaaaa Aaaaaaaaa Aaaaaaaaaa Aaaaaa Aaaa Aaaaaaaaaa Aa Aaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaa Aaa Aaa Aaaa Aaaa Aa Aaaaaa Aaaaaaaa Aaaaaa Aaaaa Aaa Aaaaa Aaaa Aaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaa Aaaaa Aaaaaaaaaaaaa Aa Aaaaaaaaa Aaaaaaaa Aaaa Aaaaa Aa Aaaaaaaa Aa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aaaaaaa Aa Aaaaaaaaaaaaaaaaa
a Aaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaaaaaaa Aaaaaaaa Aaaa Aaaaaaa Aaaaaaaaaaa Aaaaaaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaaa Aaaaaaaa Aaaaaaaaa Aaaa Aaaaaaa Aaaaaaaaaa Aa Aaa Aaaa Aaaaaaaaa Aaa Aaaaaaa Aaaaaaaa Aaa Aa Aaaaaaaa Aaaaaaaa Aaaaaaaa Aaaaaaaaaa Aaaa Aaa Aaaaaaaa Aaaaaaa a Aaaa Aaaaaa Aaaa Aaa Aaaaaaaaaaaaaaaa Aaaaa Aa Aaaaaa Aaaaa Aaa Aaaaa Aaaaaaa Aaaaa Aaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaaaaaaa Aaaaaaa Aaaaaaa Aaaaaaa Aaaa Aaaaaaaaa Aaaa Aaaaaaaaaaaaaa Aaaaaaaa Aaaaaaaaa
a Aaaaaaaaaaaaaaa Aaaaaa Aa Aaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaaa Aaaa Aaaaaaaa Aaaaaaa Aaaaaaaaaaaaa Aaa Aaa Aaaaaaaaaa Aa Aaaaaa Aaaaaaaaaaa Aaaaaa Aaaaa Aaaa a Aaaaa a Aaaaaa Aaaaaaa Aaaa Aaaaa Aaaaaa Aaa Aaaaa Aaaaaa Aaaa Aaaaaaaa Aaaaaaa Aaaaaaaa Aaaaaaaa Aaaaaaaaaa Aaaaaaaa Aaa Aaaaaaa Aaaaaaa Aaaaaa Aaa Aaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaa
🔒Multiple re-entrancy audit patterns identified across document lifecycle operations, with concrete starting points for variant discovery
Subscribe to read more