diff --git a/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption.js b/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption.js
index fd67da9e5c43a..3e3014e8d2470 100644
--- a/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption.js
+++ b/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption.js
@@ -3,6 +3,10 @@
"use strict";
add_task(async function test_cross_docGroup_adoption() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.content_web_accessible.enabled", true]],
+ });
+
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"http://example.com/"
@@ -16,6 +20,7 @@ add_task(async function test_cross_docGroup_adoption() {
js: ["content-script.js"],
},
],
+ web_accessible_resources: ["current.html"],
},
files: {
diff --git a/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption_xhr.js b/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption_xhr.js
index dd0f6c4f870fb..a1b7fcee2c837 100644
--- a/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption_xhr.js
+++ b/browser/components/extensions/test/browser/browser_ext_contentscript_cross_docGroup_adoption_xhr.js
@@ -3,6 +3,10 @@
"use strict";
add_task(async function test_cross_docGroup_adoption() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.content_web_accessible.enabled", true]],
+ });
+
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"http://example.com/"
@@ -16,6 +20,7 @@ add_task(async function test_cross_docGroup_adoption() {
js: ["content-script.js"],
},
],
+ web_accessible_resources: ["blank.html"],
},
files: {
diff --git a/browser/components/extensions/test/browser/browser_ext_nontab_process_switch.js b/browser/components/extensions/test/browser/browser_ext_nontab_process_switch.js
index 0c05408b17523..b81c3756aa36e 100644
--- a/browser/components/extensions/test/browser/browser_ext_nontab_process_switch.js
+++ b/browser/components/extensions/test/browser/browser_ext_nontab_process_switch.js
@@ -1,6 +1,10 @@
"use strict";
add_task(async function process_switch_in_sidebars_popups() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.content_web_accessible.enabled", true]],
+ });
+
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary", // To automatically show sidebar on load.
manifest: {
@@ -17,6 +21,7 @@ add_task(async function process_switch_in_sidebars_popups() {
browser_action: {
default_popup: "page.html?popup",
},
+ web_accessible_resources: ["page.html"],
},
files: {
"page.html": ``,
diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp
index b00edbd6adc96..070122b07587b 100644
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -693,11 +693,26 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
basePrin->GetURI(getter_AddRefs(sourceURI));
if (!sourceURI) {
if (basePrin->Is()) {
+ // If the target addon is MV3 or the pref is on we require extension
+ // resources loaded from content to be listed in web_accessible_resources.
+ auto* targetPolicy =
+ ExtensionPolicyService::GetSingleton().GetByURL(aTargetURI);
+ bool contentAccessRequired =
+ targetPolicy &&
+ (targetPolicy->ManifestVersion() > 2 ||
+ StaticPrefs::extensions_content_web_accessible_enabled());
auto expanded = basePrin->As();
const auto& allowList = expanded->AllowList();
// Only report errors when all principals fail.
+ // With expanded principals, which are used by extension content scripts,
+ // we check only against non-extension principals for access to extension
+ // resource to enforce making those resources explicitly web accessible.
uint32_t flags = aFlags | nsIScriptSecurityManager::DONT_REPORT_ERRORS;
for (size_t i = 0; i < allowList.Length() - 1; i++) {
+ if (contentAccessRequired &&
+ BasePrincipal::Cast(allowList[i])->AddonPolicy()) {
+ continue;
+ }
nsresult rv = CheckLoadURIWithPrincipal(allowList[i], aTargetURI, flags,
aInnerWindowID);
if (NS_SUCCEEDED(rv)) {
@@ -706,6 +721,19 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
}
}
+ if (contentAccessRequired &&
+ BasePrincipal::Cast(allowList.LastElement())->AddonPolicy()) {
+ bool reportErrors =
+ !(aFlags & nsIScriptSecurityManager::DONT_REPORT_ERRORS);
+ if (reportErrors) {
+ ReportError("CheckLoadURI", sourceURI, aTargetURI,
+ allowList.LastElement()
+ ->OriginAttributesRef()
+ .mPrivateBrowsingId > 0,
+ aInnerWindowID);
+ }
+ return NS_ERROR_DOM_BAD_URI;
+ }
// Report errors (if requested) for the last principal.
return CheckLoadURIWithPrincipal(allowList.LastElement(), aTargetURI,
aFlags, aInnerWindowID);
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
index 5b19ffbd25fc7..09e92c56cde09 100644
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -4670,6 +4670,13 @@
# Prefs starting with "extensions."
#---------------------------------------------------------------------------
+# Pref that enforces the use of web_accessible_resources for content loads.
+# This behavior is default for MV3. The pref controls this for MV2.
+- name: extensions.content_web_accessible.enabled
+ type: bool
+ value: false
+ mirror: always
+
# Whether the InstallTrigger implementation should be enabled (or hidden and
# none of its methods available).
- name: extensions.InstallTriggerImpl.enabled
diff --git a/toolkit/components/extensions/test/mochitest/test_ext_extension_iframe_messaging.html b/toolkit/components/extensions/test/mochitest/test_ext_extension_iframe_messaging.html
index 170457dd6c98d..403782ab7d5c5 100644
--- a/toolkit/components/extensions/test/mochitest/test_ext_extension_iframe_messaging.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_extension_iframe_messaging.html
@@ -13,13 +13,20 @@
"use strict";
add_task(async function test_moz_extension_iframe_messaging() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["extensions.content_web_accessible.enabled", true],
+ ],
+ });
+
let extension = ExtensionTestUtils.loadExtension({
manifest: {
- "content_scripts": [{
- "js": ["cs.js"],
- "matches": ["http://mochi.test/*/file_sample.html"],
+ content_scripts: [{
+ js: ["cs.js"],
+ matches: ["http://mochi.test/*/file_sample.html"],
}],
- "permissions": ["tabs"],
+ web_accessible_resources: ["iframe.html"],
+ permissions: ["tabs"],
},
files: {
"cs.js"() {
diff --git a/toolkit/components/extensions/test/mochitest/test_ext_web_accessible_resources.html b/toolkit/components/extensions/test/mochitest/test_ext_web_accessible_resources.html
index 13bd18602e98d..0158a3bd194ca 100644
--- a/toolkit/components/extensions/test/mochitest/test_ext_web_accessible_resources.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_web_accessible_resources.html
@@ -12,11 +12,10 @@