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 @@