Medium CVSS 4.3 webkit Bypass 🔧 Commit mapped

Overview

Medium
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionA malicious iframe may use another website’s download settings
ComponentWebKit UIProcess
Bug ClassBypass
Tracker311288
Fix commit4b574bf8287b (WebKit/WebKit) +284/-1
CWECWE-1021
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
CISA KEVNot listed
CreditedKhiem Tran
Disclosed2026-05-11

Background

Safe Browsing check
An asynchronous check that flags navigations to known-unsafe URLs and shows a warning before proceeding.
Download policy action
A navigation whose response is handled as a download rather than displayed; it must still respect Safe Browsing.
Main frame vs subframe
Downloads and warnings are handled differently for the top-level frame versus an embedded iframe.
Per-navigation state
Safe Browsing results are tied to a specific API::Navigation; using another navigation’s state confuses the security decision.

Root Cause Analysis

When a navigation resolves to a Download, WebKit must still honor the Safe Browsing check associated with that navigation.

Pre-patch, a download policy decision could proceed without waiting for the navigation’s Safe Browsing check to finish (and without correctly applying its result per frame), so a download initiated from a subframe/iframe could bypass or mis-apply the Safe Browsing warning – described as a malicious iframe using another website’s download settings, i.e. the download was not gated on the correct, per-navigation Safe Browsing state.

The fix adds a completion mechanism on API::Navigation – whenSafeBrowsingCheckCompletes(callback), which runs immediately if no check is ongoing else queues the callback, and fireSafeBrowsingCheckCompletionCallbacks(), invoked from WebPageProxy::beginSafeBrowsingCheck when the check finishes (using std::exchange to drain the queue). In WebPageProxy::decidePolicyForNavigationAction, when policyAction == Download and a Safe Browsing check is ongoing, the download decision is deferred via whenSafeBrowsingCheckCompletes; on completion, if a Safe Browsing warning matched, the download is refused: for a non-main frame it fails the provisional navigation and returns PolicyAction::Ignore, and for the main frame it shows the browsing warning and only proceeds per the user’s choice.

The restored invariant is that a download is authorized only after the navigation’s own Safe Browsing check completes and only if it did not match, so a subframe cannot slip a download past the warning or inherit another frame’s settings.

Key insight
Download decisions were not gated on the completion of the navigation’s own Safe Browsing check, so a malicious iframe could slip a download past the warning; deferring the download until the per-navigation check completes and honoring a match closes it.

Attack Path

  1. Embed a malicious iframe A page hosts a cross-origin iframe that initiates a navigation which will resolve to a download.
  2. Race the Safe Browsing check The iframe triggers the download policy decision while the navigation’s Safe Browsing check is still ongoing.
  3. Bypass the warning Pre-patch, the download proceeds without waiting for / correctly applying the per-navigation Safe Browsing result, effectively using the wrong frame’s download handling.
  4. Unsafe download A download that Safe Browsing would have blocked is allowed, or attributed to another site’s settings, in the UIProcess.

Impact Assessment

A security-policy bypass (not memory safety): a subframe-initiated download could proceed without correctly waiting for or applying the navigation’s Safe Browsing check, letting a malicious iframe evade the warning or use another site’s download handling. It executes in the UIProcess and affects download safety/attribution; no code-execution path. Rated medium.

Changed Functions

FunctionChangeNotes
Navigation::whenSafeBrowsingCheckCompletes / fireSafeBrowsingCheckCompletionCallbacks
Source/WebKit/UIProcess/API/APINavigation.cpp
added Adds a per-navigation completion queue: run now if no check is ongoing, else queue; fire drains it via std::exchange when the check finishes.
WebPageProxy::beginSafeBrowsingCheck
Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
modified Fires the navigation's Safe Browsing completion callbacks once the check is no longer ongoing.
WebPageProxy::decidePolicyForNavigationAction
Source/WebKit/UIProcess/WebPageProxy.cpp
modified For PolicyAction::Download with an ongoing Safe Browsing check, defers via whenSafeBrowsingCheckCompletes and, on a match, ignores the download (subframe: fail provisional navigation; main frame: show warning).

Files Changed

  • Source/WebKit/UIProcess/API/APINavigation.cpp
  • Source/WebKit/UIProcess/API/APINavigation.h
  • Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
  • Source/WebKit/UIProcess/WebPageProxy.cpp
  • Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SafeBrowsing.mm

Audit Directions

  • Other policy actions vs Safe Browsing
    Audit decidePolicyForNavigationAction/Response branches (Use, Download, Ignore) to confirm each waits for and applies the navigation’s Safe Browsing result.
  • Per-frame attribution
    Review how frame vs main-frame and frameInfo are used in download and warning handling to prevent one frame inheriting another’s settings.
  • Async check completion races
    grep for safeBrowsingCheckOngoing()/completion callbacks to ensure no security decision proceeds while a check is pending.

Original Bug Report

The reporter's bug is still restricted on the tracker.