← All issues

[11] [WebCore] Defer Safe Browsing download decision until lookup completes

Severity: Medium | Component: WebKit UIProcess navigation policy | 4b574bf

Rated Medium because the diff defers the PolicyAction::Download decision until safeBrowsingCheckOngoing() is false; pre-fix any URL that triggered the download policy and whose Safe Browsing lookup had not yet returned skipped the warning entirely, but the impact is constrained to URLs the user already chose to download.

decidePolicyForNavigationAction and decidePolicyForResponseShared no longer apply Download synchronously when safeBrowsingCheckOngoing(). A per-navigation completion-callback queue defers the decision until the lookup completes, at which point the callback re-checks safeBrowsingWarning() and blocks or proceeds.

Source/WebKit/UIProcess/WebPageProxy.cpp

- if (action == PolicyAction::Download && navigation->safeBrowsingWarning()) {
- // show warning
- }
+ if (action == PolicyAction::Download) {
+ if (navigation->safeBrowsingCheckOngoing()) {
+ navigation->queueDownloadDecision(WTFMove(continuation));
+ return;
+ }
+ // re-check warning, block or proceed
+ }

Safe Browsing TOCTOU on the download path: a slow remote lookup that would later flag the URL was bypassed because the download was already handed off to WKDownload.

A new completion-callback queue on API::Navigation is drained when safeBrowsingCheckOngoing() falls. Subframe block produces a provisional-load error; main-frame block surfaces the interstitial. The *PostTimeout regression test exercises the ~250 ms listener timeout window where the gap was reliably reproducible.

WebKit's Safe Browsing lookup runs asynchronously against a remote service. Normal page loads can surface a late interstitial after navigation start, but downloads, once handed to WKDownload, cannot be retracted by a late warning.

Pre-fix, the policy handler evaluated safeBrowsingWarning() synchronously when applying Download. If the lookup had not returned (the typical case for slow or remote lookups), safeBrowsingWarning() returned null and the download proceeded. The TOCTOU window between policy decision and download start was the entire lookup latency.

🔒

The interaction between an asynchronous reputation check and a non-retractable policy action is examined in detail, along with the practical attacker model and the limits of what this bypass yields.

Subscribe to read more

🔒

Four reusable audit patterns identified, covering other consumers of the same asynchronous gate and the broader class of non-retractable policy decisions in the UIProcess.

Subscribe to read more