Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in Extensions
DescriptionInsufficient policy enforcement in Extensions
ComponentExtensions
Bug ClassLogic Error
Tracker498864176
Fix commit72af0053522f (chromium/src) +28/-6
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
of modified
switch
chrome/browser/extensions/extension_management.cc
modified
TEST_P
chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
modified

Files Changed

  • chrome/browser/extensions/extension_management.cc
  • chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
  • extensions/browser/mv2_deprecation_impact_checker.cc
From 72af0053522f6b7a10684d6692f156cd84c8cc3c Mon Sep 17 00:00:00 2001
From: Devlin Cronin <[email protected]>
Date: Wed, 13 May 2026 16:23:45 -0700
Subject: [PATCH] [Extensions] Include Manifest::TYPE_USER_SCRIPT in mv2 checker

Extensions of TYPE_USER_SCRIPT are largely treated as "extensions"
throughout Chrome -- they have access to extension APIs, are considered
extensions for feature availability, are shown in the
chrome://extensions page as extensions, etc.

Include them in the MV2DeprecationImpactChecker to ensure MV2 user
scripts are also disabled.

Very few* users have any extensions installed of TYPE_USER_SCRIPT, so
this shouldn't affect significant amounts of users, and any that are
affected are using deprecated extensions (thus, disabling them is
working as intended).

Note: This is not to be confused with *user script managers*, a
class of extension that leverages the browser.userScripts API.

*Internal stats only, sorry.

Bug: 498864176
Change-Id: I7310fa1f1411290dac935fd6d899bd72daafdcc0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7846377
Reviewed-by: Tim <[email protected]>
Commit-Queue: Tim <[email protected]>
Auto-Submit: Devlin Cronin <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1630304}
---

diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc
index aed401d..782658fd 100644
--- a/chrome/browser/extensions/extension_management.cc
+++ b/chrome/browser/extensions/extension_management.cc
@@ -375,10 +375,12 @@
           extensions_features::kExtensionsManifestV3Only) ||
       manifest_version >= 3;
 
-  // Manifest version policy only supports normal extensions and Chrome OS login
-  // screen extension.
+  // Manifest version policy only supports normal extensions, Chrome OS login
+  // screen extensions, and user scripts (which are largely treated as
+  // extensions).
   if (manifest_type != Manifest::Type::TYPE_EXTENSION &&
-      manifest_type != Manifest::Type::TYPE_LOGIN_SCREEN_EXTENSION) {
+      manifest_type != Manifest::Type::TYPE_LOGIN_SCREEN_EXTENSION &&
+      manifest_type != Manifest::Type::TYPE_USER_SCRIPT) {
     return enabled_by_default;
   }
   switch (global_settings_->manifest_v2_setting) {
@@ -411,7 +413,8 @@
     return false;
   }
   if (manifest_type != Manifest::Type::TYPE_EXTENSION &&
-      manifest_type != Manifest::Type::TYPE_LOGIN_SCREEN_EXTENSION) {
+      manifest_type != Manifest::Type::TYPE_LOGIN_SCREEN_EXTENSION &&
+      manifest_type != Manifest::Type::TYPE_USER_SCRIPT) {
     return false;
   }
 
diff --git a/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc b/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
index 00bbb1a7..8ad8b73e 100644
--- a/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
+++ b/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
@@ -511,6 +511,22 @@
   EXPECT_FALSE(impact_checker()->IsExtensionAffected(*hosted_app));
 }
 
+// Tests that user script MV2 extensions are properly considered affected by
+// the MV2 deprecation experiment.
+TEST_P(MV2DeprecationImpactCheckerUnitTest, UserScriptsAreAffected) {
+  scoped_refptr<const Extension> user_script =
+      ExtensionBuilder("user script")
+          .SetLocation(mojom::ManifestLocation::kInternal)
+          .SetManifestVersion(2)
+          .SetManifestKey("converted_from_user_script", true)
+          .Build();
+  ASSERT_EQ(Manifest::TYPE_USER_SCRIPT, user_script->GetType());
+
+  bool expected_affected = policy_level() != MV2PolicyLevel::kAllowed;
+  EXPECT_EQ(expected_affected,
+            impact_checker()->IsExtensionAffected(*user_script));
+}
+
 // Tests the allowlist is taken into account.
 TEST_P(MV2DeprecationImpactCheckerUnitTestWithAllowlist, AllowlistWorks) {
   scoped_refptr<const Extension> ext_a =
diff --git a/extensions/browser/mv2_deprecation_impact_checker.cc b/extensions/browser/mv2_deprecation_impact_checker.cc
index 4b7d9ec8..36d21ed 100644
--- a/extensions/browser/mv2_deprecation_impact_checker.cc
+++ b/extensions/browser/mv2_deprecation_impact_checker.cc
@@ -62,9 +62,12 @@
     return false;
   }
 
-  // Only extensions (not platform apps, etc).
+  // Only extensions (not platform apps, etc). User scripts are treated as
+  // extensions for the sake of APIs and in presentation to the user, so we
+  // include them here.
   if (manifest_type != Manifest::TYPE_EXTENSION &&
-      manifest_type != Manifest::TYPE_LOGIN_SCREEN_EXTENSION) {
+      manifest_type != Manifest::TYPE_LOGIN_SCREEN_EXTENSION &&
+      manifest_type != Manifest::TYPE_USER_SCRIPT) {
     return false;
   }
 
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc b/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
index 00bbb1a7..8ad8b73e 100644
--- a/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
+++ b/chrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc
@@ -511,6 +511,22 @@
   EXPECT_FALSE(impact_checker()->IsExtensionAffected(*hosted_app));
 }
 
+// Tests that user script MV2 extensions are properly considered affected by
+// the MV2 deprecation experiment.
+TEST_P(MV2DeprecationImpactCheckerUnitTest, UserScriptsAreAffected) {
+  scoped_refptr<const Extension> user_script =
+      ExtensionBuilder("user script")
+          .SetLocation(mojom::ManifestLocation::kInternal)
+          .SetManifestVersion(2)
+          .SetManifestKey("converted_from_user_script", true)
+          .Build();
+  ASSERT_EQ(Manifest::TYPE_USER_SCRIPT, user_script->GetType());
+
+  bool expected_affected = policy_level() != MV2PolicyLevel::kAllowed;
+  EXPECT_EQ(expected_affected,
+            impact_checker()->IsExtensionAffected(*user_script));
+}
+
 // Tests the allowlist is taken into account.
 TEST_P(MV2DeprecationImpactCheckerUnitTestWithAllowlist, AllowlistWorks) {
   scoped_refptr<const Extension> ext_a =
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.