Medium CVSS 6.5 chrome Input Validation 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
6.5
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in DevTools
DescriptionInsufficient validation of untrusted input in DevTools
ComponentDevTools
Sub-componentDevTools
Bug ClassInput Validation
Tracker503197481
Fix commit8bd52544c5cf (chromium/src) +31/-4
CWECWE-20 (Improper input validation)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
CISA KEVNot listed
Creditedlebr0nli of National Yang Ming Chiao Tung University, Dept. of CS, Security and Systems Lab
Reported2026-04-16 (per vendor advisory)
Fix landed2026-05-19 (public git)
Disclosed2026-06-02
Patch gapNot computed: mapped commit cites a different bug, not this CVE's bug.

Changed Functions

FunctionChangeNotes
if
chrome/browser/devtools/protocol/target_handler_android.cc
modified
IN_PROC_BROWSER_TEST_F
chrome/browser/extensions/api/debugger/debugger_apitest.cc
modified

Files Changed

  • chrome/browser/devtools/protocol/target_handler_android.cc
  • chrome/browser/devtools/protocol/target_handler_android.h
  • chrome/browser/extensions/api/debugger/debugger_apitest.cc
  • content/browser/devtools/render_frame_devtools_agent_host.cc
From 8bd52544c5cfb9b1108cc9235dc24885e2525aa5 Mon Sep 17 00:00:00 2001
From: Danil Somsikov <dsv@chromium.org>
Date: Tue, 19 May 2026 09:54:00 -0700
Subject: [PATCH] [DevTools] Add missing trust checks in TargetHandlerAndroid::CreateTarget

Untrusted DevTools clients were able to bypass restrictions and open
arbitrary `devtools://`, `chrome-untrusted://` URLs by using the
Target.createTarget CDP command on Android. The desktop implementation
(TargetHandler::CreateTarget) was previously patched for this issue
(crbug.com/503197481), but the Android port accepted the `is_trusted` and
`may_read_local_files` parameters in its constructor without ever
storing or evaluating them.

This CL fixes the vulnerability by:

1. Storing `is_trusted` and `may_read_local_files` as member variables
   in `TargetHandlerAndroid`.

2. Adding URL scheme validation in `TargetHandlerAndroid::CreateTarget`
   to reject privileged schemes from untrusted clients and block
   creation of targets with local files when not permitted, matching
   the desktop behavior.

3. Enabling the `CreateTargetToUntrustedWebUI` test for Android in
   `debugger_apitest.cc` to ensure ongoing coverage.

Bug: 512249559
Change-Id: I304e44a5585288f81197252b090bb4d6dab0b1a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7857154
Reviewed-by: Finnur Thorarinsson <finnur@chromium.org>
Auto-Submit: Danil Somsikov <dsv@chromium.org>
Reviewed-by: Alex Rudenko <alexrudenko@chromium.org>
Commit-Queue: Danil Somsikov <dsv@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1632957}
---

diff --git a/chrome/browser/devtools/protocol/target_handler_android.cc b/chrome/browser/devtools/protocol/target_handler_android.cc
index 578fe99e..70ffafbc 100644
--- a/chrome/browser/devtools/protocol/target_handler_android.cc
+++ b/chrome/browser/devtools/protocol/target_handler_android.cc
@@ -8,12 +8,16 @@
 #include "chrome/browser/ui/android/tab_model/tab_model.h"
 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/common/url_utils.h"
+#include "url/url_constants.h"
 
 using content::WebContents;
 
 TargetHandlerAndroid::TargetHandlerAndroid(protocol::UberDispatcher* dispatcher,
                                            bool is_trusted,
-                                           bool may_read_local_files) {
+                                           bool may_read_local_files)
+    : is_trusted_(is_trusted), may_read_local_files_(may_read_local_files) {
   protocol::Target::Dispatcher::wire(dispatcher, this);
 }
 
@@ -58,8 +62,29 @@
   TabModel* tab_model = models[0];
   CHECK(tab_model);
 
+  GURL gurl(url);
+  if (gurl.is_empty()) {
+    gurl = GURL(url::kAboutBlankURL);
+  }
+
+  GURL inner_url = gurl;
+  if (gurl.SchemeIs(content::kViewSourceScheme)) {
+    inner_url = GURL(gurl.GetContent());
+  }
+
+  if (!is_trusted_ && (inner_url.SchemeIs(content::kChromeUIUntrustedScheme) ||
+                       inner_url.SchemeIs(content::kChromeDevToolsScheme))) {
+    return protocol::Response::ServerError(
+        "Navigating to a URL with a privileged scheme is not allowed");
+  }
+
+  if (!may_read_local_files_ && inner_url.SchemeIsFile()) {
+    return protocol::Response::ServerError(
+        "Creating a target with a local URL is not allowed");
+  }
+
   WebContents* web_contents =
-      tab_model->CreateNewTabForDevTools(GURL(url), new_window.value_or(false));
+      tab_model->CreateNewTabForDevTools(gurl, new_window.value_or(false));
   if (!web_contents) {
     return protocol::Response::ServerError("Could not create a Tab");
   }
diff --git a/chrome/browser/devtools/protocol/target_handler_android.h b/chrome/browser/devtools/protocol/target_handler_android.h
index ba693fab6..c092c1d 100644
--- a/chrome/browser/devtools/protocol/target_handler_android.h
+++ b/chrome/browser/devtools/protocol/target_handler_android.h
@@ -46,6 +46,8 @@
       std::string* out_target_id) override;
 
  private:
+  bool is_trusted_ = false;
+  bool may_read_local_files_ = false;
   RemoteLocations remote_locations_;
 };
 
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
index 4570311..934b79e 100644
--- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
@@ -1150,7 +1150,6 @@
 }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-// TODO(crbug.com/441339825): Fails on desktop Android.
 // Tests that Target.createTarget to WebUI origins are blocked.
 IN_PROC_BROWSER_TEST_F(DebuggerExtensionApiTest, CreateTargetToUntrustedWebUI) {
   ASSERT_TRUE(RunExtensionTest("debugger_create_target_to_untrusted_webui"))
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index b55c73d0..c6cd2b7 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -579,8 +579,9 @@
 
   RenderFrameHostImpl* old_host = frame_host_;
   ChangeFrameHostAndObservedProcess(frame_host);
-  if (IsAttached())
+  if (IsAttached()) {
     UpdateRawHeadersAccess(old_host, nullptr);
+  }
 
   UpdateFrameAlive();
 }
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
index 4570311..934b79e 100644
--- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
@@ -1150,7 +1150,6 @@
 }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-// TODO(crbug.com/441339825): Fails on desktop Android.
 // Tests that Target.createTarget to WebUI origins are blocked.
 IN_PROC_BROWSER_TEST_F(DebuggerExtensionApiTest, CreateTargetToUntrustedWebUI) {
   ASSERT_TRUE(RunExtensionTest("debugger_create_target_to_untrusted_webui"))
Loading diff…

Original Bug Report

reported by al...@gmail.com

Incomplete patch for Issue 439058242: Untrusted DevTools clients can still navigate window to arbitrary `devtools://` URLs

redacted
View on issue tracker