summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_csp_custom_policies.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_csp_custom_policies.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_csp_custom_policies.js303
1 files changed, 303 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_csp_custom_policies.js b/toolkit/components/extensions/test/xpcshell/test_csp_custom_policies.js
new file mode 100644
index 0000000000..c860d73cc8
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_csp_custom_policies.js
@@ -0,0 +1,303 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+const { Preferences } = ChromeUtils.importESModule(
+ "resource://gre/modules/Preferences.sys.mjs"
+);
+
+const ADDON_ID = "test@web.extension";
+
+const aps = Cc["@mozilla.org/addons/policy-service;1"].getService(
+ Ci.nsIAddonPolicyService
+);
+
+const v2_csp = Preferences.get(
+ "extensions.webextensions.base-content-security-policy"
+);
+const v3_csp = Preferences.get(
+ "extensions.webextensions.base-content-security-policy.v3"
+);
+
+add_task(async function test_invalid_addon_csp() {
+ await Assert.throws(
+ () => aps.getBaseCSP("invalid@missing"),
+ /NS_ERROR_ILLEGAL_VALUE/,
+ "no base csp for non-existent addon"
+ );
+ await Assert.throws(
+ () => aps.getExtensionPageCSP("invalid@missing"),
+ /NS_ERROR_ILLEGAL_VALUE/,
+ "no extension page csp for non-existent addon"
+ );
+});
+
+add_task(async function test_policy_csp() {
+ equal(
+ aps.defaultCSP,
+ Preferences.get("extensions.webextensions.default-content-security-policy"),
+ "Expected default CSP value"
+ );
+
+ const CUSTOM_POLICY = "script-src: 'self' https://xpcshell.test.custom.csp";
+
+ let tests = [
+ {
+ name: "manifest version 2, no custom policy",
+ policyData: {},
+ expectedPolicy: aps.defaultCSP,
+ },
+ {
+ name: "manifest version 2, no custom policy",
+ policyData: {
+ manifestVersion: 2,
+ },
+ expectedPolicy: aps.defaultCSP,
+ },
+ {
+ name: "version 2 custom extension policy",
+ policyData: {
+ extensionPageCSP: CUSTOM_POLICY,
+ },
+ expectedPolicy: CUSTOM_POLICY,
+ },
+ {
+ name: "manifest version 2 set, custom extension policy",
+ policyData: {
+ manifestVersion: 2,
+ extensionPageCSP: CUSTOM_POLICY,
+ },
+ expectedPolicy: CUSTOM_POLICY,
+ },
+ {
+ name: "manifest version 3, no custom policy",
+ policyData: {
+ manifestVersion: 3,
+ },
+ expectedPolicy: aps.defaultCSPV3,
+ },
+ {
+ name: "manifest 3 version set, custom extensionPage policy",
+ policyData: {
+ manifestVersion: 3,
+ extensionPageCSP: CUSTOM_POLICY,
+ },
+ expectedPolicy: CUSTOM_POLICY,
+ },
+ ];
+
+ let policy = null;
+
+ function setExtensionCSP({ manifestVersion, extensionPageCSP }) {
+ if (policy) {
+ policy.active = false;
+ }
+
+ policy = new WebExtensionPolicy({
+ id: ADDON_ID,
+ mozExtensionHostname: ADDON_ID,
+ baseURL: "file:///",
+
+ allowedOrigins: new MatchPatternSet([]),
+ localizeCallback() {},
+
+ manifestVersion,
+ extensionPageCSP,
+ });
+
+ policy.active = true;
+ }
+
+ for (let test of tests) {
+ info(test.name);
+ setExtensionCSP(test.policyData);
+ equal(
+ aps.getBaseCSP(ADDON_ID),
+ test.policyData.manifestVersion == 3 ? v3_csp : v2_csp,
+ "baseCSP is correct"
+ );
+ equal(
+ aps.getExtensionPageCSP(ADDON_ID),
+ test.expectedPolicy,
+ "extensionPageCSP is correct"
+ );
+ }
+});
+
+add_task(async function test_extension_csp() {
+ Services.prefs.setBoolPref("extensions.manifestV3.enabled", true);
+
+ ExtensionTestUtils.failOnSchemaWarnings(false);
+
+ let extension_pages = "script-src 'self'; img-src 'none'";
+
+ let tests = [
+ {
+ name: "manifest_v2 invalid csp results in default csp used",
+ manifest: {
+ content_security_policy: `script-src 'none'`,
+ },
+ expectedPolicy: aps.defaultCSP,
+ },
+ {
+ name: "manifest_v2 allows https protocol",
+ manifest: {
+ manifest_version: 2,
+ content_security_policy: `script-src 'self' https://example.com`,
+ },
+ expectedPolicy: `script-src 'self' https://example.com`,
+ },
+ {
+ name: "manifest_v2 allows unsafe-eval",
+ manifest: {
+ manifest_version: 2,
+ content_security_policy: `script-src 'self' 'unsafe-eval'`,
+ },
+ expectedPolicy: `script-src 'self' 'unsafe-eval'`,
+ },
+ {
+ name: "manifest_v2 allows wasm-unsafe-eval",
+ manifest: {
+ manifest_version: 2,
+ content_security_policy: `script-src 'self' 'wasm-unsafe-eval'`,
+ },
+ expectedPolicy: `script-src 'self' 'wasm-unsafe-eval'`,
+ },
+ {
+ // object-src used to require local sources, but now we accept anything.
+ name: "manifest_v2 allows object-src, with non-local sources",
+ manifest: {
+ manifest_version: 2,
+ content_security_policy: `script-src 'self'; object-src https:'`,
+ },
+ expectedPolicy: `script-src 'self'; object-src https:'`,
+ },
+ {
+ name: "manifest_v3 invalid csp results in default csp used",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages: `script-src 'none'`,
+ },
+ },
+ expectedPolicy: aps.defaultCSPV3,
+ },
+ {
+ name: "manifest_v3 forbidden protocol results in default csp used",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages: `script-src 'self' https://*`,
+ },
+ },
+ expectedPolicy: aps.defaultCSPV3,
+ },
+ {
+ name: "manifest_v3 forbidden eval results in default csp used",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages: `script-src 'self' 'unsafe-eval'`,
+ },
+ },
+ expectedPolicy: aps.defaultCSPV3,
+ },
+ {
+ name: "manifest_v3 disallows localhost",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages: `script-src 'self' https://localhost`,
+ },
+ },
+ expectedPolicy: aps.defaultCSPV3,
+ },
+ {
+ name: "manifest_v3 disallows 127.0.0.1",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages: `script-src 'self' https://127.0.0.1`,
+ },
+ },
+ expectedPolicy: aps.defaultCSPV3,
+ },
+ {
+ name: "manifest_v3 allows wasm-unsafe-eval",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages: `script-src 'self' 'wasm-unsafe-eval'`,
+ },
+ },
+ expectedPolicy: `script-src 'self' 'wasm-unsafe-eval'`,
+ },
+ {
+ // object-src used to require local sources, but now we accept anything.
+ name: "manifest_v3 allows object-src, with non-local sources",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages: `script-src 'self'; object-src https:'`,
+ },
+ },
+ expectedPolicy: `script-src 'self'; object-src https:'`,
+ },
+ {
+ name: "manifest_v2 csp",
+ manifest: {
+ manifest_version: 2,
+ content_security_policy: extension_pages,
+ },
+ expectedPolicy: extension_pages,
+ },
+ {
+ name: "manifest_v2 with no csp, expect default",
+ manifest: {
+ manifest_version: 2,
+ },
+ expectedPolicy: aps.defaultCSP,
+ },
+ {
+ name: "manifest_v3 used with no csp, expect default",
+ manifest: {
+ manifest_version: 3,
+ },
+ expectedPolicy: aps.defaultCSPV3,
+ },
+ {
+ name: "manifest_v3 syntax used",
+ manifest: {
+ manifest_version: 3,
+ content_security_policy: {
+ extension_pages,
+ },
+ },
+ expectedPolicy: extension_pages,
+ },
+ ];
+
+ for (let test of tests) {
+ info(test.name);
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: test.manifest,
+ });
+ await extension.startup();
+ let policy = WebExtensionPolicy.getByID(extension.id);
+ equal(
+ policy.baseCSP,
+ test.manifest.manifest_version == 3 ? v3_csp : v2_csp,
+ "baseCSP is correct"
+ );
+ equal(
+ policy.extensionPageCSP,
+ test.expectedPolicy,
+ "extensionPageCSP is correct."
+ );
+ await extension.unload();
+ }
+
+ ExtensionTestUtils.failOnSchemaWarnings(true);
+
+ Services.prefs.clearUserPref("extensions.manifestV3.enabled");
+});