← WebKit — 2026-W37
2ae84d79b1afd1cf37254670db04b32d3c1f9c38 ProvisionalPageProxy::didStartProvisionalLoadForFrame should validate web process supplied URL
severity medium
class Spoofing
confidence 0.8
signal score 10.97
Source/WTF/
patch-now
Primitive: compromised WebContent passing an arbitrary URL to ProvisionalPageProxy::didStartProvisionalLoadForFrame (provisional/address-bar URL spoof)
Triage note: Adds MESSAGE_CHECK that the url equals navigation->currentRequest().url() or targetItem->url() before setting m_provisionalLoadURL, gated on SecurityFlags::radar180469521 ('Validate URL passed to ProvisionalPageProxy::didStartProvisionalLoadForFrame by the WebContent process'). Classic IPC-validation fix against a lying renderer.
Triage note: Adds MESSAGE_CHECK that the url equals navigation->currentRequest().url() or targetItem->url() before setting m_provisionalLoadURL, gated on SecurityFlags::radar180469521 ('Validate URL passed to ProvisionalPageProxy::didStartProvisionalLoadForFrame by the WebContent process'). Classic IPC-validation fix against a lying renderer.
Structural signals: smartptr_member_added (+6.47), null_guard (+1.2), msg_soft (+1.0), area:Source/WTF/ (+1.0), surgical (+1.3)
Commit message
ProvisionalPageProxy::didStartProvisionalLoadForFrame should validate web process supplied URL
https://bugs.webkit.org/show_bug.cgi?id=323706
rdar://180469521
Reviewed by Brady Eidson.
The URL passed into ProvisionalPageProxy::didStartProvisionalLoadForFrame by the web
process via IPC is later on used to decide if a process swap should happen. So the
UI process should validate that this URL is what we expect and not some arbitrary
URL that could lead to an incorrect process swap decision.
The web process passes this URL in to indicate what URL is it going to load. The
UI process already knows this URL. It's stored in the Navigation object in the
current request. Ideally, we would simply use the UI process stored URL and not
even have the web process pass in a URL. But there is a valid edge case in which
the passed in URL is different that what's held in this current request.
In the API test ProcessSwap.CrossSiteServerRedirectDuringBackForwardNavigation,
we navigate to a.com, then b.com, then set up a handler so that a.com redirects
to c.com. Then, since the b/f cache is disabled, going back should redirect to
c.com and be in an entirely new process. In this case, the web process thinks
that it's loading a back-forward list item with a.com, and that's the URL it passes
in. But when making the policy decision, the UI process already realized that
we'd be redirecting to c.com and the new ProvisionalPageProxy's Navigation's
current request is already set to hold c.com.
So we validate that the URL passed in by the UI process is either the URL held
by the current request or the URL of the back forward list item that this navigation
is targeting (if there is one).
This is covered by a new layout test:
http/tests/ipc/provisional-page-forged-provisional-url-message-check.html
* LayoutTests/http/tests/ipc/provisional-page-forged-provisional-url-message-check-expected.txt: Added.
* LayoutTests/http/tests/ipc/provisional-page-forged-provisional-url-message-check.html: Added.
* LayoutTests/http/tests/ipc/resources/provisional-page-forged-provisional-url-go-back.html: Added.
* Source/WebKit/UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::didStartProvisionalLoadForFrame):
* Source/WTF/Scripts/Preferences/SecurityFlags.yaml:
* LayoutTests/TestExpectations:
Identifier: 316606.698@safari-7625-branch
Before / after
Loading diff…
On This Page