← 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 fix queues the continuation against the navigation's ongoing-check state. The queue runs the queued decision when the lookup completes; re-checking safeBrowsingWarning() then catches the late-arriving verdict. Subframe and main-frame paths diverge in how the block surfaces but share the queue.

This weakens Safe Browsing enforcement on the download path; the fix restores enforcement parity with the page-load path.