Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* -*- 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");
});