← All issues

[9] Download Prompt Origin Spoofing via Back-Forward Navigation

Severity: Medium | Component: WebKit UIProcess | a9f2dfa

Rated Medium because the observable effect is download prompt origin misattribution (UI-level trust confusion), which facilitates social engineering but does not constitute code execution or memory corruption. Confidence is 0.88 based on the clear guard additions and the commit message's detailed description of the attack scenarios.

Adds two early-return guards in NavigationResponse::navigationInitiatingFrame(). When the navigation has a targetItem() (back-forward navigation) or isRequestFromClientOrUserInput() (user-typed URL / client-initiated load), the method now returns nullptr instead of returning the frame info of the currently displayed page.

Source/WebKit/UIProcess/API/APINavigationResponse.cpp

FrameInfo* NavigationResponse::navigationInitiatingFrame()
{
if (!m_navigation)
return nullptr;
 
+ if (m_navigation->targetItem() || m_navigation->isRequestFromClientOrUserInput())
+ return nullptr;
+
auto& frameInfo = m_navigation->originatingFrameInfo();
if (!frameInfo)
return nullptr;
 
RefPtr frame = WebKit::WebFrameProxy::webFrame(frameInfo->frameID);
m_sourceFrame = FrameInfo::create(WebKit::FrameInfoData { *frameInfo });
return m_sourceFrame.get();
}

Tools/TestWebKitAPI/Tests/WebKit/WKWebView/Navigation.mm

+TEST(Navigation, NavigationInitiatingFrameInGoBackNavigation)
+{
+ ...
+ navigationDelegate.get().decidePolicyForNavigationResponse = ^(WKNavigationResponse *response, void (^completionHandler)(WKNavigationResponsePolicy)) {
+ EXPECT_NULL(response._navigationInitiatingFrame);
+ done = true;
+ completionHandler(WKNavigationResponsePolicyAllow);
+ };
+ [webView _clearBackForwardCache];
+ [webView goBack];
+ ...
+}

Incorrect origin attribution for navigation-initiating frame across back-forward and client-initiated navigation types.

When WebKit processes a navigation response, it calls the delegate method webView:decidePolicyForNavigationResponse:decisionHandler: and passes a WKNavigationResponse object. Embedding clients (like Safari) may use the _navigationInitiatingFrame property on this response to display which site initiated a download or navigation. The Navigation object tracks metadata including originatingFrameInfo() (the frame that started the navigation), targetItem() (non-null for back-forward list navigations), and isRequestFromClientOrUserInput() (true for navigations initiated by the embedding app or user input like typing a URL).

NavigationResponse::navigationInitiatingFrame() unconditionally returned the originating frame info for all navigation types. For back-forward navigations and client-initiated/user-input navigations, the originating frame info refers to the page currently displayed in the WebView — not the entity that actually initiated the navigation. The commit message describes the concrete attack scenario: navigate to site1.com, navigate to site2.com, go back (with a malicious script intervening to start a download) — the prompt says "site2.com wants to start a download" even though site2 did not initiate it.

🔒

Explores the origin attribution logic and how navigation type metadata can be weaponized for UI-level spoofing

Subscribe to read more

🔒

Multiple audit directions identified for navigation origin attribution patterns across WebKit's UIProcess delegate APIs

Subscribe to read more