[1] CSP bypass in sandboxed srcdoc iframes
Severity: High | Component: WebCore loader / DocumentWriter | b4390e8
Rated High because the observable effect is a script-injection / CSP-bypass primitive in any document with a sandboxed srcdoc iframe, the analyst's confidence is 0.92, and four pre-existing WPT failures (location change, window.open, two form submissions) provide commit-backed evidence that the same single-line condition was responsible for a wider family of mis-attributions.
Source/WebCore/loader/DocumentWriter.cpp
- if (currentHistoryItem && currentHistoryItem->policyContainer()) {
+ if (triggeringAction && triggeringAction->type() == NavigationType::BackForward && currentHistoryItem && currentHistoryItem->policyContainer()) {
const auto& policyContainerFromHistory = currentHistoryItem->policyContainer();
ASSERT(policyContainerFromHistory);
document->inheritPolicyContainerFrom(*policyContainerFromHistory);
LayoutTests/http/tests/security/contentSecurityPolicy/iframe-srcdoc-import-bypass.html
+ iframe1.srcdoc = srcdocContent;
+ iframe2.srcdoc = srcdocContent.replaceAll(iframe1.id, iframe2.id);
+<iframe id="iframe1" sandbox="allow-scripts"></iframe>
+<iframe id="iframe2" sandbox="allow-scripts" srcdoc=""></iframe>
Patch Details
DocumentWriter::begin() previously inherited the new document's PolicyContainer from the current HistoryItem whenever that item carried a non-null policy container. The fix narrows the condition: history-based inheritance only triggers when a triggeringAction is present and its NavigationType is BackForward. All other navigation forms — including dynamic srcdoc mutation on a sandboxed iframe — fall through to the spec-mandated initiator-based inheritance. The WPT inheritance-from-initiator expectation file flips four FAIL→PASS results (location change, window.open, two form submission variants), and a new layout test demonstrates a sandboxed iframe loading a cross-origin module via dynamic import() after a script-driven srcdoc assignment.
Wrong policy-container source selected for non-back/forward navigations: history-item inheritance applied where initiator inheritance was required.
Background
A PolicyContainer is the WebCore aggregate that holds a document's CSP, referrer policy, and cross-origin policies. The HTML spec says srcdoc documents — having no network response of their own — must inherit their policy container from their initiator (the document that triggered the navigation). For history traversal, by contrast, the document's HistoryItem carries a snapshot of the original policy container so that back/forward restores the document with its original policy. DocumentWriter::begin() runs early in new-document construction, before any script in the new document executes, and is responsible for selecting which container the new document adopts.
Analysis
Before the fix, the loader took the simplest possible heuristic: "if there is a history policy container, use it." For a back/forward traversal that's the spec; for a fresh navigation triggered by a script-driven srcdoc mutation, it isn't — the iframe's stored history container does not contain the parent's CSP. So the new document inherited a permissive (or absent) policy where the spec demanded the strict CSP of the parent that just wrote srcdoc.
Aaa Aaaaaaaaaa Aaaa Aaaaaaaaaaaa Aaa Aaaaaaaa Aaa Aaaaaaaaa Aaaaaaa Aaaa Aaaa Aa Aaaaaaaa Aaaaaaaaaa Aaa Aaaa Aaaaaaaaaaaa Aaa Aaaaaaaa Aaaaaaaa Aaaa Aaaaaa Aaa Aaaaaaa a Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaa Aa Aaaaa Aaa Aaaaa Aaaa Aaaaaaaaa Aaaaaaa Aaa Aaaaaaaa Aaaaaaaaaaa Aaaaaaa Aaaa Aaa Aaaa Aaa Aaaaa Aaaa Aaaa Aa Aaaa a Aaaaaaaa Aaaaaaa Aaaaaaaaaaaaaa Aaa Aaaa Aaaaaaaaaaa a Aaaaaaaa Aaaaaaa Aaa Aaaa Aaaa Aaaaaaaa Aaaaaaaaaaa Aaa Aaaaaaaaaaa Aaaaaa Aa Aaaaaa Aaaaaa Aa Aaaaaaaaaaaaaaaa Aaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaa Aaa Aaaaa Aaaaaaaa Aaa Aaaaaaaaa Aaaaaaaa Aaaaaaaa Aaa Aa Aaaaa Aaa Aaaa Aaaa Aa Aaaaaaa Aaaaaaa Aaaaaaaaaa Aa Aaaaaaaaaaaaaa Aaaaaa Aa Aaaaaaaa Aaa Aaa Aaaaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaa Aaaaa Aaaaaaaa Aaaa Aaaaaa Aaa Aaaaaaaaaaa Aaaa a Aaaaaaaaaaaaa Aaaa Aaaa a Aaaaaaaa Aaaaaaaaa Aaaaaaaaaaa Aaa Aaa Aaaaaaaa Aaaaaaaa Aaaaaaa Aaaaaaa Aaa Aaaaaaaaaaa Aaa Aaaaaaaa Aaaaaaaaaa Aaaaaaa
🔒The general mechanics of CSP-inheritance for sandboxed srcdoc iframes are walked through, with attention to which navigation forms previously consulted the wrong policy source and what that meant for an attacker holding only an HTML-injection primitive.
Subscribe to read more
Audit directions
a Aaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaa Aaaaaaaaaaa Aaaa Aa Aaaaaaaaaaaa Aaaaaaa Aa Aaaaaaaaaa Aaaaaaa Aaaaa Aaaa Aa Aaaaaaa Aaaaaa Aaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaaaaaaaaa Aaaaaaaaaaaa Aaaa Aaaaa Aaaaaaaaaaa Aaaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaaaaaaaaa Aaaaa Aa Aaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaa Aaa Aaaa Aaa Aaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaaaaaa Aaaaaaaaa Aaaaa Aaaaaaaa Aaaaaaa Aaaa Aa Aaaaaaa Aaaa Aaa Aaaaaaaaaaaa Aaaaa Aaaaaa a Aaaaaaaaaaaaa a Aaaaaaaaaaaaa Aaaaaaaaaaaa Aaaaa Aa Aaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaa Aa Aaaa Aaaaaaaa Aaaaaaa Aaaaaaaaaa Aaaaaaa Aaaaaa Aaa Aaaaaaa Aaaaaaa Aaaaa Aaa Aaa Aaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aa Aaaaaaa Aaaaaa Aa Aaaaaaaaaaaaaaaaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaa Aaaaaaaaaaa Aaaa Aaaaa Aaaaaaa Aaaaaaaa Aaaaaaaaaaa Aaaaaa Aaaaa Aaaaaaaaaa Aaaaaaaaaaa Aaaaa Aaaaa Aaaaaa a Aaaaaa Aaaaaaaa a Aaaaaaa Aaaaaaaaaaa Aaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaaaa Aaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a Aaaaaaaa Aaa Aaaaaaaaaaa Aaaa Aaaa Aaaaaaaaaaaaaaaaaaaaa a Aaaaaaaaaaaaaaaaaa Aaaaaaaa a Aaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaaaaaaaaaaaa Aaaaaaaa Aa Aaa Aaaaaaaaaa Aaaaaaaa Aaaaaa Aaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aaaa Aaaa Aaaaaa Aaaaaaaa Aaaaaa Aaa Aaaaaaaa Aaaaaaaaaa Aaaa Aaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaa Aaaa Aaaaaaaaaaa Aaa Aaaaaaaa Aaaaaaaaa
🔒Several reusable audit patterns covering policy-container inheritance across multiple loader entry points and local-scheme document constructions, with concrete grep starting points.
Subscribe to read more