[4] FrameLoader inherits empty registrable domain for about:blank popups
Severity: Medium | Component: WebCore FrameLoader | d6c7e00
Rated Medium because the diff fixes a reliable third-party-cookie-blocking bypass reachable from any first-party page via window.open('about:blank'); impact is privacy/tracking, not memory safety.
When an about:blank popup made cross-origin requests, its firstPartyForCookies was set to about:blank, which has an empty registrable domain. thirdPartyCookieBlockingDecisionForRequest() returns ThirdPartyCookieBlockingDecision::None for empty domains, bypassing third-party cookie blocking. FrameLoader::updateFirstPartyForCookies() should inherit the opener's firstPartyForCookies when the main frame URL is an owner-inherited document.
Source/WebCore/loader/FrameLoader.cpp
void FrameLoader::updateFirstPartyForCookies()
{
- if (RefPtr page = m_frame->page())
- setFirstPartyForCookies(page->mainFrameURL());
+ RefPtr page = m_frame->page();
+ if (!page)
+ return;
+
+ auto firstPartyForCookies = page->mainFrameURL();
+ if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(firstPartyForCookies)) {
+ if (RefPtr opener = dynamicDowncast<LocalFrame>(page->mainFrame().opener())) {
+ if (RefPtr openerDocument = opener->document())
+ firstPartyForCookies = openerDocument->firstPartyForCookies();
+ }
+ }
+
+ setFirstPartyForCookies(firstPartyForCookies);
}
LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-blocking-about-blank-popup.html
+ case "#step2":
+ var popup = window.open("about:blank");
+ popup.eval(
+ "fetch('" + thirdPartyOrigin + "/cookies/resources/echo-cookies.py', { credentials: 'include' })" + ...
+ );
Patch Details
updateFirstPartyForCookies() previously set the frame's firstPartyForCookies to page->mainFrameURL() unconditionally. The fix adds a check: if the main frame URL is one that should inherit its security origin from its owner (via SecurityPolicy::shouldInheritSecurityOriginFromOwner()), it walks to page->mainFrame().opener() (downcast to LocalFrame), retrieves the opener document's firstPartyForCookies(), and uses that instead.
Failure to mirror opener/parent inheritance into the first-party-for-cookies field when the document URL is an owner-inherited scheme like about:blank.
Background
firstPartyForCookies is a per-frame URL recorded on outgoing requests; the network layer uses its registrable domain (eTLD+1) as the "first party" when deciding whether a cookie destination is first- or third-party. For about:blank and other opaque schemes, the registrable domain is the empty string. WebKit's third-party cookie blocking (Intelligent Tracking Prevention) suppresses cookies on cross-site subresource requests when the destination has been classified as a tracker; the decision is gated on thirdPartyCookieBlockingDecisionForRequest(). Per HTML spec, an about:blank document inherits its security origin from the browsing context that created it; SecurityPolicy::shouldInheritSecurityOriginFromOwner(url) returns true for the set of URL schemes (about:blank, about:srcdoc, data: etc.) that follow this rule.
Analysis
When a page opened an about:blank popup, the popup's main frame URL was literally about:blank. updateFirstPartyForCookies() then set firstPartyForCookies on the popup's frame to that URL. When the popup subsequently issued a cross-origin request, the network layer computed the registrable domain of about:blank — empty. thirdPartyCookieBlockingDecisionForRequest() treats an empty registrable domain as None, i.e. "do not block", because there is no meaningful first party to compare against.
Aaaa a Aaaaaaaaaaa Aaaa Aa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaa a Aaaaa Aaaaa Aaaa Aaaaa Aaa Aa Aaaaaaaaaaaaaa Aaaaaa Aaa Aaaaaa Aaaaa Aaaaaaaaaaaa Aaaaaaaaaaaa Aaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaa Aaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaa Aaa Aaaaaaaaaaa Aaaaaa Aa Aaaaaa Aaa Aaa Aaaaaaaaaaaaaa Aaaaaaaaaaa Aaaaaaa Aaa Aaaaaaaaaaaaaaaaa Aaa Aaaaaaaa Aa Aaa Aaaaaaa a Aaaaaaa Aaa Aaaa Aaa Aaaaaaaaaa Aaaa Aaaaaaaaaaaa Aaaa Aaaaaaaaaaa a Aaaaaaaaaaaaaaaaaaaaaaaa
Aaa Aaa Aaaa Aaaaaaa Aaa Aaaaaaaaaa Aaaaaa Aaaaa Aaa Aaaaaaaaaaaaa Aa Aaa Aaaaaa Aa a Aaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaaaaaa Aaa Aaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aa Aaaaa Aaaaa Aaaaa Aaaaaaaa Aaa Aaaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaaa Aaa Aaaaaaaaaaa Aaaaaa Aaaaaaaa Aaaaa Aaaaaaaa Aaaa Aaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaa Aaa Aaaaaaaa Aaaaa Aaaaaaa Aaaa Aaaaa Aaaaaaaaa Aaaaaaaa Aaaaaaa Aaa a Aaaaaaa Aaaaaaaaa Aaaaaaaaaaa Aaaaaaaaaaa Aaaaaaa Aaaaaa Aaa Aaa Aaaa Aaaaaaaaa Aaa Aaaaaaaa Aaa Aaa Aaaaa Aaaaa Aaaaaaa Aaaaaaaa Aaa Aaa Aaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaa Aa a Aaaaaaaa Aaaaa Aa Aaaaaaaa Aaaaaaa Aaa Aaa Aaaa a Aaa Aaaaaa Aaa Aaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaa Aaaaaaaaa Aaaaaaaa Aaaaaaaaaaaaa Aaaaa Aaa Aaaaaaaaaaaaa Aaaaa Aaaaa Aaaa Aaaaaa Aaa Aaaa Aaaaaaaaaaa a Aaaaaaaaa Aaa Aaaaaaa Aaaaa Aaaaaaaa Aaaaaaaaaa Aa Aaa Aaaaa Aaaaaaa
🔒Detailed analysis of the cookie-policy boundary that this opener-inheritance gap weakens, and the realistic conditions under which it can be triggered from web content
Subscribe to read more
Audit directions
a Aaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaa Aaaaa Aaa a Aaaaa Aaaaaaaaaaa Aaaaaa Aa Aaaaaa Aaaaa Aaaaaaa Aa Aaaaaaaaa Aaaaa Aaa Aa Aaaaaaaaaaaaaaaaaa Aaaaa Aaa Aaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaa Aa Aaaaaa Aaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaa Aaaa Aaa Aaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaa Aaa Aaaaa Aaaa Aaaa Aaa Aaaaaaa Aa Aaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaa Aaaaa Aaaa Aaaaaaaaaaaa Aaa Aaa Aaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaa Aaa Aaaaa Aaaaaaaa Aa Aaa Aaaaaa Aa a Aaaaaaaaaaaaaa Aaaaa Aaaaaaa a Aaaaaaaaaaaaa Aaaaaa Aaaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaa Aaaaaaa Aaa Aaaaaaaaaa Aaaaaaaaaaa Aa Aaaaaaaaa Aa Aaa Aaaaaaaaaa Aaaaaaa Aaa Aaaa Aaaaa Aaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaa Aaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aaaaa Aaaaa Aaaaaaaa Aaaaaaaa Aaaaa a Aaaaaaaa Aaaaaaaa Aaaaaaa Aaa Aaaaaaaaaaaa Aaaaaaaaaaaaa Aaa Aaaaaa Aaaaaaaaa Aaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaa Aaaaaaa a Aa Aaaaaa Aaaa Aaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaa Aaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaa Aaaaaaaaaaa Aaaaaa Aa Aa Aaaaaa Aaaaaaaa Aaaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaaaa Aaaaaaaaa Aaaaaaaa Aaaaaaa Aaaaaaaaaaa Aaaaaaaa Aaaaaaaaaaa Aaaaaaaa Aa Aaaaaaa Aaaa Aa Aaaaa Aaaaaaaaaaa Aaaaaaaaaaa Aaaaaa Aa Aaaaaaa Aaaaaaaaaaaaaa Aaaaaa Aaaa Aa Aaaaaaa
🔒Multiple reusable audit patterns identified across WebKit's first-party / origin-inheritance machinery, with concrete grep starting points and a site-isolation caveat worth examining
Subscribe to read more