Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: f23ffb5a845006c8efbdf8a18a15f69a617fec00
      
https://github.com/WebKit/WebKit/commit/f23ffb5a845006c8efbdf8a18a15f69a617fec00
  Author: Chris Dumez <[email protected]>
  Date:   2026-07-01 (Wed, 01 Jul 2026)

  Changed paths:
    M Source/WebCore/loader/DocumentLoader.cpp
    M Source/WebKit/UIProcess/API/APINavigation.h
    M Source/WebKit/UIProcess/WebPageProxy.cpp

  Log Message:
  -----------
  Compromised Web Content can use a navigation-response Download policy on a 
data: URL to write attacker-controlled bytes to disk
https://bugs.webkit.org/show_bug.cgi?id=315004
rdar://177019828

Reviewed by Basuke Suzuki.

A compromised Web Content process can cause the UI process to write 
attacker-chosen
bytes to ~/Downloads/Unknown with no user interaction, no `download` attribute, 
and
no Content-Disposition header. The renderer opens a popup navigation to a
data:application/octet-stream;base64,<payload> URL; because the MIME type is not
showable, the navigation delegate's stock policy returns
WKNavigationResponsePolicyDownload. 
WebPageProxy::receivedNavigationResponsePolicyDecision
unconditionally mints a real DownloadProxy for the data: URL, the natural
WebFrame::startDownload -> NetworkConnectionToWebProcess::StartDownload flow 
runs,
and the data: URL bytes land on disk. The renderer-supplied user-gesture token 
is
forged to bypass the popup blocker; everything downstream is stock behavior.

Refuse PolicyAction::Download for data: URLs in
WebPageProxy::receivedNavigationResponsePolicyDecision unless the navigation was
driven by the API client. The carve-out uses 
Navigation::m_requestIsFromClientInput
(set only by UIProcess paths such as -loadRequest:), not the renderer-supplied
isRequestFromClientOrUserInput flag. Legitimate data: URL downloads via
<a href="data:..." download> use the navigation-action policy, and explicit 
downloads
via -[WKWebView startDownloadUsingRequest:] use a separate API path -- neither
reaches receivedNavigationResponsePolicyDecision.

As defense in depth, also extend the existing disallowDataRequest() check in
DocumentLoader::continueAfterContentPolicy to the PolicyAction::Download branch 
so
the same restriction that already applies to PolicyAction::Use applies to 
downloads.
The Web Content process is the compromised party in this report, so this is not 
the
primary defense, but it keeps non-Cocoa ports and future flows consistent.

* Source/WebCore/loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::continueAfterContentPolicy):
* Source/WebKit/UIProcess/API/APINavigation.h:
(API::Navigation::isFromAPIClientRequest const):
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedNavigationResponsePolicyDecision):

Originally-landed-as: 305413.929@safari-7624-branch (8aeb259135a8). 
rdar://181074672
Canonical link: https://commits.webkit.org/316344@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to