Low watch ✔︎ verified CVSS 8.8 chrome Policy Bypass 🔧 Commit mapped

Overview

Low
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in DevTools
DescriptionInsufficient policy enforcement in DevTools
ComponentDevTools
Bug ClassPolicy Bypass
Action tierwatch — logic/policy bug — security-relevant, no memory-unsafety — factors set by independent review by AI
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.
Independent review by AIConfirmed
Reviewer notes: Citations ExtensionServer.ts:1617-1619 and :1626, the E_FAILED guard, and the HostConfig plumbing all check out. Minor: unverified DevToolsUIBindings:: qualifier. 'No check prevented' ignores isAllowedOnTarget checks at 1571/1607, whose behavior is not shown.
A second, independent AI reviewer (not a human) re-derived this analysis from the fixing commit and the vendor advisory, looking for errors.
Tracker375959766
Fix commit4ad0d072cba9 (devtools/devtools-frontend) +10/-0
Related commitsa68c336b7734 companion · chromium/src
CWECWE-693
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
Creditedasnine
Reported2024-10-28 · bounty $1000 (per vendor advisory)
Fix landed2026-06-15 (public git)
Disclosed2026-07-29
Patch gap44 days — fix public in source before the advisory

Background

`chrome.devtools.inspectedWindow.eval`
a DevTools extension API that evaluates a JavaScript expression in the context of the inspected page.
`ExtensionServer`
the DevTools frontend component that services requests from DevTools extensions, including eval.
`HostConfig`
a configuration object the Chromium backend passes to the DevTools frontend describing enabled features and permissions.
`--extensions-on-chrome-urls`
a Chrome switch permitting extensions to operate on otherwise-restricted extension/chrome URLs.

Root Cause Analysis

Re-analyzed on 2026-10-03 against the actual fix commit 4ad0d072cba9. An earlier analysis was withdrawn because it had been written against a commit that was not the security fix (48f965098f72).

In the pre-fix front_end/panels/common/ExtensionServer.ts evaluate path, when the inspected frame’s URL used the chrome-extension: scheme and its origin differed from the requesting extension’s origin, the code only classified the target as Host.UserMetrics.ExtensionEvalTarget.OTHER_EXTENSION for metrics (ExtensionServer.ts:1617-1619) and then proceeded to evaluate (ExtensionServer.ts:1626 void context.evaluate(...)). The handler does run extension?.isAllowedOnTarget(...) checks earlier (ExtensionServer.ts:1571, :1607), but their implementation is not shown. Per the commit message and the new EvalRestrictedOnOtherExtension test (which expects E_FAILED only after the fix), those checks did not block a different extension’s chrome-extension: page, so pre-fix nothing in the shown code denied the OTHER_EXTENSION case and a DevTools extension could run script in another extension’s context — insufficient policy enforcement.

The fix (commit 4ad0d072…, devtools/devtools-frontend) adds, in the OTHER_EXTENSION branch, a guard that returns this.status.E_FAILED('Access to extension URLs is restricted; use --extensions-on-chrome-urls to enable.') unless Root.Runtime.hostConfig.extensionsOnChromeUrls?.enabled is true (added diff lines). The companion chromium/src CL (a68c336b…) supplies that state by setting response_dict.Set("extensionsOnChromeUrls", base::DictValue().Set("enabled", extensions::switches::AreExtensionsOnExtensionURLsAllowed())) in the host-config dictionary (added diff), and the frontend declares the new ExtensionsOnChromeUrls interface plus the extensionsOnChromeUrls HostConfig member in front_end/core/root/Runtime.ts (added diff). This tightens the path: cross-extension evaluation is now blocked by default and only allowed when the backend reports the switch is enabled. The SAME_EXTENSION and web-page cases are unchanged.

Key insight
Cross-extension eval was only measured, never gated; the fix adds an authorization check keyed to the backend-reported extensionsOnChromeUrls permission so it is denied unless explicitly enabled.

Attack Path

  1. Load a DevTools extension An installed DevTools extension registers a devtools_page and uses the inspectedWindow.eval API.
  2. Target another extension's page It arranges for the inspected frame to be a different extension’s chrome-extension: origin, hitting the OTHER_EXTENSION branch (ExtensionServer.ts:1617-1619). (inferred)
  3. Evaluate without restriction Pre-fix the frontend proceeds to context.evaluate(...) (ExtensionServer.ts:1626), running the expression in the other extension’s context.
  4. Privilege escalation Script executes with the victim extension’s origin/privileges. (inferred)

Impact Assessment

A DevTools extension could evaluate JavaScript in another extension’s execution context, a policy/authorization bypass that the commit message ties to potential privilege escalation. The advisory rates this low severity with no in-the-wild exploitation. Any escalation beyond cross-context script execution is (inferred).

Changed Functions

FunctionChangeNotes
if
front_end/panels/common/ExtensionServer.ts
modified

Files Changed

  • front_end/core/root/Runtime.ts
  • front_end/panels/common/ExtensionServer.ts

Audit Directions

  • Metrics vs enforcement
    Treat code that only classifies or records a sensitive case (e.g. OTHER_EXTENSION) as a red flag that an authorization decision may be missing.
  • Frontend-trusted config
    Verify that DevTools frontend permission gates read a HostConfig flag the browser actually sets, so an absent/stale flag fails closed.
  • Cross-origin eval
    Audit extension eval/injection paths for a check that the target origin belongs to the requesting extension before evaluating.
diff --git a/front_end/core/root/Runtime.ts b/front_end/core/root/Runtime.ts
index cc64bd5..b68121a 100644
--- a/front_end/core/root/Runtime.ts
+++ b/front_end/core/root/Runtime.ts
@@ -600,6 +600,10 @@
   enabled: boolean;
 }
 
+interface ExtensionsOnChromeUrls {
+  enabled: boolean;
+}
+
 interface DevToolsFlexibleLayout {
   verticalDrawerEnabled: boolean;
 }
@@ -702,6 +706,7 @@
   devToolsAdsPanel: DevToolsAdsPanel,
   devToolsUseGcaApi: UseGcaApi,
   devToolsPlusButton: DevToolsPlusButton,
+  extensionsOnChromeUrls: ExtensionsOnChromeUrls,
 }>;
 
 /**
diff --git a/front_end/panels/common/ExtensionServer.ts b/front_end/panels/common/ExtensionServer.ts
index 3ba18b4..ec2342a 100644
--- a/front_end/panels/common/ExtensionServer.ts
+++ b/front_end/panels/common/ExtensionServer.ts
@@ -12,6 +12,7 @@
 import * as i18n from '../../core/i18n/i18n.js';
 import * as Platform from '../../core/platform/platform.js';
 import * as _ProtocolClient from '../../core/protocol_client/protocol_client.js';  // eslint-disable-line @typescript-eslint/no-unused-vars
+import * as Root from '../../core/root/root.js';
 import * as SDK from '../../core/sdk/sdk.js';
 import type * as Protocol from '../../generated/protocol.js';
 import * as Bindings from '../../models/bindings/bindings.js';
@@ -1616,6 +1617,10 @@
           targetType = Host.UserMetrics.ExtensionEvalTarget.SAME_EXTENSION;
         } else {
           targetType = Host.UserMetrics.ExtensionEvalTarget.OTHER_EXTENSION;
+          if (!Root.Runtime.hostConfig.extensionsOnChromeUrls?.enabled) {
+            return this.status.E_FAILED(
+                'Access to extension URLs is restricted; use --extensions-on-chrome-urls to enable.');
+          }
         }
       }
       Host.userMetrics.extensionEvalTarget(targetType);
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.