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

Overview

High
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in WebView tag
DescriptionInsufficient policy enforcement in WebView tag
ComponentWebView tag
Sub-componentExtensions
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.
Tracker463155954
Fix commit28628907f24e (chromium/src) +71/-0
CWECWE-862
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedGal Weizman
Reported2025-11-23 (per vendor advisory)
Fix landed2025-12-30 (public git)
Disclosed2026-01-06
Patch gap7 days — fix public in source before the advisory

Background

WebView tag (`<webview>`)
a guest-view element that embeds a separate guest WebContents, used by Chrome Apps and by browser WebUI such as chrome://chrome-signin, which hosts the accounts.google.com sign-in flow inside a WebView.
Declarative Net Request (DNR)
an extension API (declarativeNetRequest permission) that lets an extension register static or dynamic rules that the browser matches against network requests, with actions such as block, redirect, upgrade scheme or modify headers.
`RulesetManager`
the browser-side component in extensions/browser/api/declarative_net_request/ruleset_manager.cc that decides whether a request is eligible for DNR evaluation and then matches it against the installed extensions’ rulesets.
`WebRequestInfo::is_web_view`
a flag on the per-request info object marking that the request was made by a WebView guest.

Root Cause Analysis

The patch changes one hunk in extensions/browser/api/declarative_net_request/ruleset_manager.cc: a boolean eligibility check that already returns false for several excluded request types, and otherwise falls through to return true. The enclosing function’s name is not shown in the hunk. From the shape of the code it is likely the RulesetManager helper that decides whether a request should be evaluated at all, but the diff does not confirm the name. Before the patch, nothing on this path excluded requests where request.is_web_view was set, so DNR rules from any installed extension were matched against network requests made by WebView guests, including the privileged chrome://chrome-signin WebView that loads accounts.google.com. That breaks the policy that extensions must not be able to act on WebView traffic, as the commit message says (“Extensions should not be able to apply DNR rules to requests originating from WebViews”).

The fix adds an early if (request.is_web_view) return false; just before the final return true;, so WebView requests are never handed to DNR rule matching. This tightens the check. The added browser test confirms the trigger: an MV3 extension with a high-priority block rule for urlFilter: "accounts.google.com" on main_frame must record no matched rules when the sign-in WebView loads.

Key insight
The DNR eligibility gate filtered out several request classes but did not filter out WebView-originated requests, so extension rules applied inside privileged embedded guests such as the Chrome sign-in WebView. The fix adds an explicit is_web_view exclusion, so DNR rules never evaluate those requests.

Attack Path

  1. Install a DNR extension The attacker gets the user to install an extension that declares declarativeNetRequest and ships a static ruleset, like the test’s block_chrome_signin extension with a priority-999 rule matching accounts.google.com main-frame requests.
  2. Victim opens a WebView-hosting surface The user opens a page that embeds a <webview>, such as chrome://chrome-signin/?reason=6, whose WebView navigates to accounts.google.com.
  3. Rules match guest traffic Before the fix, the request eligibility check returned true for the WebView’s requests, so RulesetManager matched them against the extension’s rules.
  4. Extension controls WebView requests The extension’s action (the test uses block) applies to the WebView’s traffic. With DNR’s other actions, such as redirect or header modification, the extension could also tamper with the sign-in or app WebView flow (inferred).

Impact Assessment

An installed extension with the declarativeNetRequest permission could apply its rules to network requests made by WebView guests. These include the browser’s own chrome://chrome-signin WebView and Chrome App <webview>s, which are meant to be outside extension network control. The diff shows the extension could block such requests. Redirecting or modifying sign-in traffic to interfere with or hijack account flows is (inferred) from DNR’s general capabilities and is not shown by the patch. The precondition is a malicious or compromised installed extension, and the user must open a WebView-hosting surface. Ordinary web content cannot trigger this, and no compromised renderer is needed. The vendor rates it high severity (“Insufficient policy enforcement in WebView tag”). The advisory text given here says nothing about in-the-wild exploitation.

Changed Functions

FunctionChangeNotes
if
extensions/browser/api/declarative_net_request/ruleset_manager.cc
modified

Files Changed

  • chrome/browser/apps/guest_view/web_view_browsertest.cc
  • chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/manifest.json
  • chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/rules.json
  • extensions/browser/api/declarative_net_request/ruleset_manager.cc

Audit Directions

  • Other extension request-interception paths
    Check that webRequest, declarativeWebRequest, proxy and content-setting hooks apply the same is_web_view and privileged-guest exclusions as DNR, especially for WebUI-hosted guests like chrome://chrome-signin.
  • Allow-by-default eligibility gates
    Predicates that list exclusions and end in return true silently include any new request origin (guest views, MPArch inner pages, fenced frames). Audit them for request classes added after the gate was written.
  • WebView guest privilege boundaries
    Review where guest WebContents traffic is treated like ordinary tab traffic by profile-wide services (extensions, policy, prefetch), since a privileged embedder’s guest content may need stronger isolation from extensions.
From 28628907f24e27fff20d26471482f377047db3c8 Mon Sep 17 00:00:00 2001
From: Kelvin Jiang <[email protected]>
Date: Tue, 30 Dec 2025 11:22:24 -0800
Subject: [PATCH] [Extensions] Do not apply DNR rules for Webview requests

Extensions should not be able to apply DNR rules to requests originating
from WebViews.

Bug: 463155954
Change-Id: I50bcf9d32480407cfa76bb0bfe6cab67351c43ec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7354432
Reviewed-by: Devlin Cronin <[email protected]>
Commit-Queue: Kelvin Jiang <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1563452}
---

diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 79748346..f2b0c78 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -130,6 +130,8 @@
 #include "extensions/browser/api/declarative/rules_registry.h"
 #include "extensions/browser/api/declarative/rules_registry_service.h"
 #include "extensions/browser/api/declarative/test_rules_registry.h"
+#include "extensions/browser/api/declarative_net_request/action_tracker.h"
+#include "extensions/browser/api/declarative_net_request/rules_monitor_service.h"
 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
 #include "extensions/browser/api/extensions_api_client.h"
 #include "extensions/browser/app_window/native_app_window.h"
@@ -5801,6 +5803,40 @@
                          testing::Bool(),
                          ChromeSignInWebViewTest::DescribeParams);
 
+// Check that rules from the DeclarativeNetRequest API are not matched for
+// requests originating from WebViews.
+IN_PROC_BROWSER_TEST_P(ChromeSignInWebViewTest,
+                       DeclarativeNetRequestRulesNotMatched) {
+  SKIP_FOR_MPARCH();  // TODO(crbug.com/40202416): Enable test for MPArch.
+
+  // Load an extension that blocks all main frame requests into
+  // accounts.google.com which is loaded inside the WebView in
+  // chrome://chrome-signin.
+  const auto* extension = LoadExtension(test_data_dir_.AppendASCII(
+      "api_test/declarative_net_request/block_chrome_signin"));
+
+  // Navigate to a WebUI page that contains a WebView which loads
+  // accounts.google.com.
+  const GURL signin_url{"chrome://chrome-signin/?reason=6"};
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), signin_url));
+  WaitForWebViewInDom();
+
+  // Check that no rules were matched from the extension. Note that the test
+  // would not complete if the accounts.google.com request from the WebView is
+  // blocked.
+  extensions::declarative_net_request::RulesMonitorService*
+      rules_monitor_service =
+          extensions::declarative_net_request::RulesMonitorService::Get(
+              browser()->profile());
+  ASSERT_TRUE(rules_monitor_service);
+  extensions::declarative_net_request::ActionTracker& action_tracker =
+      rules_monitor_service->action_tracker();
+
+  EXPECT_TRUE(action_tracker
+                  .GetMatchedRules(*extension, std::nullopt, base::Time::Min())
+                  .empty());
+}
+
 // This verifies the fix for http://crbug.com/667708.
 IN_PROC_BROWSER_TEST_P(ChromeSignInWebViewTest,
                        ClosingChromeSignInShouldNotCrash) {
diff --git a/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/manifest.json b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/manifest.json
new file mode 100644
index 0000000..86a7614
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/manifest.json
@@ -0,0 +1,16 @@
+{
+  "name": "Block Chrome signin page extension",
+  "declarative_net_request": {
+    "rule_resources": [{
+      "id": "1",
+      "path": "rules.json",
+      "enabled": true
+    }]
+  },
+  "manifest_version": 3,
+  "permissions": [
+    "declarativeNetRequest",
+    "declarativeNetRequestFeedback"
+  ],
+  "version": "1.0"
+}
diff --git a/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/rules.json b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/rules.json
new file mode 100644
index 0000000..7416518
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/rules.json
@@ -0,0 +1,13 @@
+[
+  {
+    "id": 1,
+    "priority": 999,
+    "action": {
+      "type": "block"
+    },
+    "condition": {
+      "urlFilter": "accounts.google.com",
+      "resourceTypes" : ["main_frame"]
+    }
+  }
+]
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
index 2b36ce05..4dadc8d 100644
--- a/extensions/browser/api/declarative_net_request/ruleset_manager.cc
+++ b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -521,6 +521,12 @@
     return false;
   }
 
+  // Declarative Net Request rules should not be matched against requests
+  // originating from WebViews.
+  if (request.is_web_view) {
+    return false;
+  }
+
   return true;
 }
 
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 79748346..f2b0c78 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -130,6 +130,8 @@
 #include "extensions/browser/api/declarative/rules_registry.h"
 #include "extensions/browser/api/declarative/rules_registry_service.h"
 #include "extensions/browser/api/declarative/test_rules_registry.h"
+#include "extensions/browser/api/declarative_net_request/action_tracker.h"
+#include "extensions/browser/api/declarative_net_request/rules_monitor_service.h"
 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
 #include "extensions/browser/api/extensions_api_client.h"
 #include "extensions/browser/app_window/native_app_window.h"
@@ -5801,6 +5803,40 @@
                          testing::Bool(),
                          ChromeSignInWebViewTest::DescribeParams);
 
+// Check that rules from the DeclarativeNetRequest API are not matched for
+// requests originating from WebViews.
+IN_PROC_BROWSER_TEST_P(ChromeSignInWebViewTest,
+                       DeclarativeNetRequestRulesNotMatched) {
+  SKIP_FOR_MPARCH();  // TODO(crbug.com/40202416): Enable test for MPArch.
+
+  // Load an extension that blocks all main frame requests into
+  // accounts.google.com which is loaded inside the WebView in
+  // chrome://chrome-signin.
+  const auto* extension = LoadExtension(test_data_dir_.AppendASCII(
+      "api_test/declarative_net_request/block_chrome_signin"));
+
+  // Navigate to a WebUI page that contains a WebView which loads
+  // accounts.google.com.
+  const GURL signin_url{"chrome://chrome-signin/?reason=6"};
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), signin_url));
+  WaitForWebViewInDom();
+
+  // Check that no rules were matched from the extension. Note that the test
+  // would not complete if the accounts.google.com request from the WebView is
+  // blocked.
+  extensions::declarative_net_request::RulesMonitorService*
+      rules_monitor_service =
+          extensions::declarative_net_request::RulesMonitorService::Get(
+              browser()->profile());
+  ASSERT_TRUE(rules_monitor_service);
+  extensions::declarative_net_request::ActionTracker& action_tracker =
+      rules_monitor_service->action_tracker();
+
+  EXPECT_TRUE(action_tracker
+                  .GetMatchedRules(*extension, std::nullopt, base::Time::Min())
+                  .empty());
+}
+
 // This verifies the fix for http://crbug.com/667708.
 IN_PROC_BROWSER_TEST_P(ChromeSignInWebViewTest,
                        ClosingChromeSignInShouldNotCrash) {
diff --git a/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/manifest.json b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/manifest.json
new file mode 100644
index 0000000..86a7614
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/manifest.json
@@ -0,0 +1,16 @@
+{
+  "name": "Block Chrome signin page extension",
+  "declarative_net_request": {
+    "rule_resources": [{
+      "id": "1",
+      "path": "rules.json",
+      "enabled": true
+    }]
+  },
+  "manifest_version": 3,
+  "permissions": [
+    "declarativeNetRequest",
+    "declarativeNetRequestFeedback"
+  ],
+  "version": "1.0"
+}
diff --git a/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/rules.json b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/rules.json
new file mode 100644
index 0000000..7416518
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/declarative_net_request/block_chrome_signin/rules.json
@@ -0,0 +1,13 @@
+[
+  {
+    "id": 1,
+    "priority": 999,
+    "action": {
+      "type": "block"
+    },
+    "condition": {
+      "urlFilter": "accounts.google.com",
+      "resourceTypes" : ["main_frame"]
+    }
+  }
+]
Loading diff…

Original Bug Report

reported by [email protected]

Extensions can hijack Gemini in the browser webview process to perform PE attacks by abusing DNR permissions, allowing stealing prompts, PII leakage, unrestricted access to camera-microphone and more


Report description

Extensions can hijack Gemini in the browser webview process to perform PE attacks by abusing DNR permissions, allowing stealing prompts, PII leakage, unrestricted access to camera-microphone and more


Bug location

Where do you want to report your vulnerability?

Chrome VRP – Report security issues affecting the Chrome browser. See program rules

Which URL (or repository) have you found the vulnerability in?

Gemini (webview) in the browser


The problem

Please describe the technical details of the vulnerability

(DEMO VID - https://drive.google.com/file/d/1rA5FdPQwvEtuskNB_qaGXIXdXksAYjma/view?usp=sharing)

New Gemini in the browser feature in Chrome allows users to activate a new window that renders a special component of a Gemini instance that combines capabilities of generating remote Gemini AI responses and manipulating the browser based on them.

This new component is very clearly a browser-level entity, baked into the browser, aiming to be a builtin enhancement of it, thus superior to websites and installed extensions.

This is clearly proven by Chrome’s implemented enforcement around this new component, where affecting it from outside isn’t allowed and explicitly blocked. For example, executing content-scripts or attaching debugger capabilities against the special component fail to take place completely.

What’s further clear is that this isn’t an origin-level decision, but a process decision, because injecting content-scripts to gemini.google.com via extensions is allowed if loaded as an ordinary website, but not when attempted against the new special component.

This expresses how Gemini in the browser is a feature that serves the browser itself and therefore must remain superior to inferior entities such as websites an extensions.

Unfortunately, it seems that DeclarativeNetRequests (DNR) permissions were not taken into account, with which a malicious extension can inject code directly under gemini.google.com within the special webview component of Gemini in the browser, thus allowing to undermine and hijack it completely.

All an attacker has to do is to use DNR to remove protecting headers (e.g. CSP, DiP, CORP, etc) and then redirect one script served by the Gemini app with an attacker controlled script.

To be more specific, here are the challenges required to tackle in order to perform the attack successfully:

  1. First, find a script that is not necessary for the Gemini web app so we can replace it with our own. For that I picked https://www.gstatic.com/feedback/js/help/prod/service/lazy.min.js and used DNR to redirect it to https://weizmangal.com/public/try.js which is a JS I control
  2. CSP won’t allow it, therefore we craft a DNR rule to drop CSP of gemini.google.com all together
  3. Within the webview context, the Gemini app counts on SAB which requires a document-isolation-policy. This is a problem because that same policy rejects my script coming from a cross-origin, so I simply replace its value to isolate-and-credentialless so that SAB works but pulling cross-origin scripts works too
  4. Next, since DNR works with https: URLs, I had to pull my malicious code from the web, but I didn’t want people to see what I’m up to online and also I needed a faster way to work than deploy scripts online every few seconds. Therefore, I implemented a mechanizm that implements the attack in B64 and sets it to the DNR URL as a query param, pointing at a constant online script that takes the B64 from the query param and executes it (this is essentially the only visible difference between each of the attached rules.json files).

Impact analysis – Please briefly explain who can exploit the vulnerability, and what they gain when doing so

(DEMO VID - https://drive.google.com/file/d/1rA5FdPQwvEtuskNB_qaGXIXdXksAYjma/view?usp=sharing)

Anyone with access to installed extensions with common DNR permissions can perform this attack, whether by tricking users into installing malicious extensions or by infecting already legit extensions into doing this (e.g. AdBlock already has necessary permissions to perform such an attack). For starters, rules.json shows how we manage to run a simple console.log under gemini.google.com within the webview.

The impact that can be achieved is as wide as the range of capabilities the Gemini in the browser process is exposed to, for example:

  1. An attacker can intercept requests and responses within the app to steal/fabricate prompt communication with Gemini (rules_intercept.json)
  2. An attacker can phish the user into interacting with fake layout to be tricked into providing sensitive information (rules_phish.json)
  3. An attacker can ride on the already established communication channel with the host of the webview (chrome://glic) and intercept post messages to either steal sensitive information or force the browser to perform sensitive actions (rules_leak_pii.json)
  4. An attacker can escalate its privileges and access capabilities it does not hold from the stance of an extension, such as camera and microphone (rules_pe.json)

All of those will be demonstrated in the attached PoC.

At first glance it might seem that most of this impact can be trivially achieved once an extension has access to DNR permissions. For example, intercepting Gemini requests and/or drawing fraudulent phishing layout can be done against the web app just as well. However, this is fundamentally different for the following reason:

As opposed to the Gemini web app, to which an extension is naturally superior, the Gemini in the browser webview is served as part of the browser, which sends a message to the user that says “this is a highly trusted component, not like websites”. Given that, undermining it is more impactful. A proof of that is how the Gemini web app is allowed to be injected with content-scripts, but when loaded within the webview, isn’t.

Not only the component can be attacked when looked at as the ordinary Gemini web app, but within this special context, new attack surface becomes available. I was able to ride on the established communication with the embedder of the webview and intercept exchanged messages between them. For example, I’ve learned how message glicBrowserGetUserProfileInfo leaks the name and gmail account that is logged into the browser on the profile level, which is not trivially accessible to extensions. Furthermore, I was able to make the host perform any operation it is designed to support coming from the app, such as opening new tabs, resizing the webview window and more.

This discovery arrives just in time, right before glicBrowserCreateTask, glicBrowserPerformActions, glicBrowserJournalSnapshot and more are fully utilized, allowing attackers to perform far more damage by learning what Gemini actors do and perhaps instruct them maliciously.

On top of that, since the process is endowed with special capabilities such as access to camera or microphone (after user settings activation), malicious code running within this process can access those without prompting the user for permission, unlike how site permissions usually work. This effectively allows an attacker coming from an extension without such power, to ride the Gemini in browser webview and access such devices without any need for user interaction (except for starting Gemini) - aka, a classic escalation of privileges attack.


The cause

What version of Chrome have you found the security issue in?

142.0.7444.176 stable

No, it is not related to a crash.

Choose the type of vulnerability

Privilege Escalation

How would you like to be publicly acknowledged for your report?

Gal Weizman

View on issue tracker