← All issues

[1] NetworkProcess origin-allowlist IPC gating

Severity: High | Component: WebKit NetworkProcess | 7143ace

Rated High because the diff confirms three IPC messages on NetworkConnectionToWebProcess were always dispatchable from any WebContent process and mutated the process-global origin access allowlist consulted by CORS/SOP; the included regression test demonstrates that a compromised renderer turns a same-origin XHR check into a cross-origin data read, which is a direct universal-CORS-bypass primitive on the Network process trust boundary.

Origin access allowlist IPC messages on NetworkConnectionToWebProcess modify a process-global allowlist with no validation, allowing a compromised WebContent process to bypass CORS for all connections. These messages are only used by TestRunner SPI. Gate them behind EnabledBy=AllowTestOnlyIPC so they are rejected unless the test-only flag is set.

Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in

- AddOriginAccessAllowListEntry(String sourceOrigin, String destinationProtocol, String destinationHost, bool allowDestinationSubdomains);
- RemoveOriginAccessAllowListEntry(String sourceOrigin, String destinationProtocol, String destinationHost, bool allowDestinationSubdomains);
- ResetOriginAccessAllowLists();
+ [EnabledBy=AllowTestOnlyOriginAccessAllowListIPC] AddOriginAccessAllowListEntry(String sourceOrigin, String destinationProtocol, String destinationHost, bool allowDestinationSubdomains);
+ [EnabledBy=AllowTestOnlyOriginAccessAllowListIPC] RemoveOriginAccessAllowListEntry(String sourceOrigin, String destinationProtocol, String destinationHost, bool allowDestinationSubdomains);
+ [EnabledBy=AllowTestOnlyOriginAccessAllowListIPC] ResetOriginAccessAllowLists();

Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml

+AllowTestOnlyOriginAccessAllowListIPC:
+ type: bool
+ status: embedder
+ exposed: [ WebKit ]
+ webcoreBinding: none
+ defaultValue:
+ WebKit:
+ default: false
+ sharedPreferenceForWebProcess: true

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

+ [webViewA stringByEvaluatingJavaScript:[NSString stringWithFormat:
+ @"IPC.sendMessage('Networking', 0,"
+ " IPC.messages.NetworkConnectionToWebProcess_AddOriginAccessAllowListEntry.name,"
+ " ["
+ " { type: 'String', value: 'http://localhost:%u' },"
+ " { type: 'String', value: 'http' },"
+ " { type: 'String', value: '127.0.0.1' },"
+ " { type: 'bool', value: 1 }"
+ " ]"
+ ")", serverPort]];
+ EXPECT_WK_STREQ(result, "FETCHED:cross-origin-data");

The patch tags three IPC messages — AddOriginAccessAllowListEntry, RemoveOriginAccessAllowListEntry, and ResetOriginAccessAllowLists — with [EnabledBy=AllowTestOnlyOriginAccessAllowListIPC] in NetworkConnectionToWebProcess.messages.in. The corresponding preference is introduced in UnifiedWebPreferences.yaml with sharedPreferenceForWebProcess: true and default: false, then wired into WebKitTestRunner (TestOptions.cpp, TestOptions.h, TestController.cpp) so layout tests can opt in. Two regression tests (AddOriginAccessAllowListEntryRequiresTestOnlyIPC and AddOriginAccessAllowListEntryAllowedWithTestOnlyIPC) drive the IPC via the IPC testing API across two WKWebViews sharing a process pool and demonstrate the bypass is reachable when the flag is off and blocked when it is.

Test-only IPC entry point exposed on the production renderer-to-network surface, allowing a compromised WebContent process to mutate process-global same-origin/CORS policy without authorization.

WebKit splits the browser into multiple processes; WebContent runs untrusted web content, and NetworkProcess performs all network I/O on its behalf, communicating via Mach IPC. NetworkConnectionToWebProcess is the per-WebContent endpoint inside NetworkProcess; the messages it accepts are declared in NetworkConnectionToWebProcess.messages.in and dispatched by code generated from that file.

The [EnabledBy=Pref] annotation on a message declaration tells the generator to inject a runtime check against the named preference — when the preference is false, the message is rejected before its handler runs. sharedPreferenceForWebProcess: true causes the preference value to be propagated from the UI process to the WebContent and Network processes so the generated check can see it.

The origin access allowlist (SecurityOrigin::addOriginAccessAllowlistEntry and its OriginAccessPatterns storage) is a process-global table of (source, protocol, host, subdomains) tuples; same-origin and CORS checks consult it, and a matching entry causes a cross-origin access to be treated as same-origin. The TestRunner SPI exposes a function so layout tests can populate this allowlist to simulate cross-origin scenarios — that is the API's only intended consumer.

The bug is a missing IPC authorization check. Before the fix, the three origin-allowlist messages on NetworkConnectionToWebProcess were always dispatchable from any WebContent process with no validation. Their handlers mutate the process-global origin allowlist that SecurityOrigin::canAccess and the CORS path consult when deciding whether a cross-origin network access is permitted. The allowlist API exists only to support TestRunner SPI, so its presence on a production IPC surface is a trust-boundary violation: a compromised WebContent process could append an entry of its choosing, and from that point onward any page loaded by any WebContent process sharing that Network process is exempted from CORS for the chosen destination.

🔒

Trust-boundary analysis and post-renderer-compromise impact assessment for a process-global policy mutation reachable over IPC.

Subscribe to read more

🔒

Multiple reusable audit patterns identified for finding similar test-only IPC surfaces that may still be ungated, with concrete starting points across the Network and GPU process IPC layers.

Subscribe to read more