[5] [Navigation API] intercept() wrongly succeeds for cross-subdomain navigations
Severity: Medium | Component: WebCore Navigation API | b537a57
Rated Medium because the observable effect is a same-origin-policy weakening that lets any subdomain intercept top-level navigations to sibling subdomains, the analyst's confidence is 0.95, and the impact is bounded to web-platform trust violation (no memory-safety primitive).
Source/WebCore/page/Navigation.cpp
const URL& documentURL = document.url();
Ref documentOrigin = document.securityOrigin();
auto targetOrigin = SecurityOrigin::create(targetURL);
- bool isSameSite = documentOrigin->isSameSiteAs(targetOrigin);
- bool isSameOrigin = documentOrigin->isSameOriginAs(targetOrigin);
- // For cross-window navigation with document.domain, we need to check same-origin rather than same-site
- // to account for document.domain modifications that make cross-origin windows same-origin-domain
- if (!isSameSite && !isSameOrigin)
+ if (!documentOrigin->isSameOriginAs(targetOrigin))
+ return false;
+
+ if (documentURL.user() != targetURL.user() || documentURL.password() != targetURL.password())
return false;
Patch Details
documentCanHaveURLRewritten previously returned false only when both isSameSiteAs and isSameOriginAs were false — a strictly weaker predicate than the spec demands. The fix replaces the composite check with two separate tests: a strict isSameOriginAs (scheme/host/port equality) and an explicit URL::user()/URL::password() comparison. Two regression tests in NavigationAPI.mm exercise cross-subdomain navigation (page1.example.com → page2.example.com) and userinfo-differing navigation, both verifying that event.intercept() now throws SecurityError.
Same-origin policy relaxation via substituting same-site for same-origin in a spec-mandated origin-equality check.
Background
The Navigation API's NavigateEvent.canIntercept boolean gates whether event.intercept() is permitted; calling intercept() when canIntercept is false throws SecurityError. Per the HTML spec, canIntercept is true only if the document's URL "can be rewritten" to the destination URL, which requires equality of scheme, username, password, host, and port. SecurityOrigin::isSameOriginAs compares (scheme, host, port); SecurityOrigin::isSameSiteAs compares the registrable domain (eTLD+1) and is therefore true for any pair of subdomains under a shared public suffix + 1 label.
Analysis
The pre-fix implementation took the form if (!isSameSite && !isSameOrigin) return false; — a De Morgan-inverted composition that means "pass if EITHER same-site OR same-origin". The stale inline comment about document.domain reveals the author's intent (prefer isSameOriginAs to account for document.domain aliasing) but the boolean shape over-relaxed to the entire eTLD+1.
Aaaaaaaaaaa Aa Aaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaa a Aaaa Aa Aaa Aaaaaaaa Aaaa Aaaaaaaaa a Aaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaa Aaaaaaaaaa Aaaaa Aaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaa Aaaaa Aa Aa a Aa Aaaaaaaa Aa Aa a Aaaa Aaaaaaa Aaaa Aaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaa Aaaaaaaa Aaaaa Aaa Aaaaaaaaaa Aaaaaaa Aaaa Aaaa Aa Aaa Aaaaaa Aaaaaaaaaa Aa Aaaaaaa Aaaaa Aaa Aaaaaaaaaaaa Aaaaaaaaaa Aa Aaaaaaaaaa Aaaaaaaaa Aaaaaaaaa Aa Aaaaaaaa Aaa Aaaaaaaa Aaaaaaa Aaaaa Aaa Aaaa Aaa Aaa Aaaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaaaaa Aaaaa Aaaaaaaaaaa Aaaaa Aaa Aaaa Aaaa Aaaaaaa Aaaaaaaaaaaaaa Aa Aaaa Aaaa Aaaa Aaaaaa Aaa Aaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaa Aaa Aa Aaaaaaaaa Aa a Aaaaaaaaa Aaaaaa Aaaaaaaaaaa Aaaaaaaaaa Aaaaaaaaa Aaaa Aaaa Aaaaa Aaaaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaa
🔒An origin-comparison primitive in a high-level Web API was implemented with the wrong predicate — the trust-boundary implications and concrete attack scenarios are explored.
Subscribe to read more
Audit directions
a Aaaaaaaaaaa Aaaa Aa a Aaaaaaaaaa Aaa Aaaaaaaaaaa Aa a Aaaaaaaaaaaaaaaaa Aaaaaaaaaaaa Aaaaa Aaaaaaa Aaaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aa a Aaaaaaaaaaaaaaaaaa Aaaaa Aaaaaaa Aaaaaaaa Aaaaaaaa Aaaaaaaaaaaaa Aaa Aa Aaaaaaaaaaaaaaa Aaaaaa Aaaa Aaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaa Aaaa Aaa Aaaa Aaaaa Aaaaaaaaa Aaaaaaaa Aaaa Aaaa Aaaaaaaa Aaaaa Aaaaaaaa
a Aaaa Aaaaaaaaaaaaaaa Aaaaaaaa Aaaaaaaaaaaaaa Aaa Aaa Aa Aaa Aaaaaa Aaaaaaaaa Aa Aaa Aaaaaa Aa a Aaa Aa Aaaa Aaa Aaaaaaaaaaaa Aa Aaaaaaaaaaaa Aaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaa Aaaaaaaaa
a Aaaaaa Aaaaaaaaaa Aaaaaaaaaaa Aaa Aaaaaaaaaa Aaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaa Aaaaaaa Aaaa Aaaa Aaaaaaaaaa Aaaaaaaaaaaaaaaa Aaaa Aaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaa Aaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaa Aaaaaaaaaa Aaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaa Aaaaa Aaaaaaaaaa Aaa Aaaaaa Aaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaaa Aaaaaa Aaaa Aaaa Aaaa Aaaaaaa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaa Aa Aaaaaa Aaaaaaaaa Aaa Aaaaaaaaaa
🔒Several reusable audit patterns identified for finding the same class of mistake elsewhere in WebKit's web-platform security predicates.
Subscribe to read more