Chrome · Extensions
CVE-2026-14047
Logic Error in Extensions
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
of |
modified | |
switchchrome/browser/extensions/extension_management.cc |
modified | |
TEST_Pchrome/browser/extensions/mv2_deprecation_impact_checker_unittest.cc |
modified |
Files Changed
chrome/browser/extensions/extension_management.ccchrome/browser/extensions/mv2_deprecation_impact_checker_unittest.ccextensions/browser/mv2_deprecation_impact_checker.cc
Patch
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.
References
On This Page