CVE-2026-20643
Overview
Background
- Navigation API intercept
- navigation.intercept()/rewrite lets a page handle a navigation; only permitted for eligible (same-origin) navigations.
- Same-site vs same-origin
- Same-site compares registrable domains; same-origin compares scheme+host+port. The API must gate on same-origin.
- URL userinfo
- The username/password in a URL, which also participates in origin/credential separation.
Root Cause Analysis
This tightens the Navigation API’s URL-rewrite eligibility to enforce the Same-Origin Policy. documentCanHaveURLRewritten() decides whether a navigation can be intercepted/rewritten (navigation.intercept).
Before the fix it allowed the rewrite when the document and target were same-SITE OR same-origin, with a comment about accommodating document.domain — so a page could intercept/rewrite a navigation to a different subdomain of the same registrable domain (same site but a different origin), a same-origin-policy bypass. It also did not compare URL credentials.
The fix replaces that logic with a strict check: return false unless documentOrigin->isSameOriginAs(targetOrigin), and additionally return false if documentURL.user() != targetURL.user() or the passwords differ.
The restored invariant is that the Navigation API may only rewrite/intercept navigations that are truly same-origin (and carry matching userinfo), so a page cannot use it to observe or manipulate cross-origin (cross-subdomain) navigations. The added API tests confirm intercept() now fails for a different subdomain and for differing username/password. Established by the diff.
Attack Path
- Load attacker page on one origin The page runs on e.g. page1.example.com and registers a navigation ’navigate’ event listener that calls event.intercept().
- Navigate to a same-site, cross-origin target It sets location.href to page2.example.com (same registrable domain, different origin) — or changes the URL userinfo.
- Intercept a cross-origin navigation Pre-patch documentCanHaveURLRewritten allowed the rewrite because it was same-site, so intercept() succeeded across origins.
- Bypass the Same-Origin Policy The handler runs for the cross-origin navigation, letting the page observe/control a navigation it should not, violating SOP.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
documentCanHaveURLRewrittenSource/WebCore/page/Navigation.cpp |
modified | Replaces the same-site-or-same-origin test with a strict same-origin requirement and additionally rejects when URL username/password differ, so the Navigation API can no longer rewrite/intercept cross-origin (cross-subdomain) navigations. |
Files Changed
Source/WebCore/page/Navigation.cppTools/TestWebKitAPI/Tests/WebKit/WKWebView/NavigationAPI.mm
Audit Directions
- same-site used where same-origin is requiredGrep isSameSiteAs used in security decisions that should use isSameOriginAs (navigation, messaging, storage).
- URL credential comparisonsCheck origin/eligibility checks that ignore url.user()/password().