summaryrefslogtreecommitdiffstats
path: root/toolkit/components/webextensions/test/mochitest/test_ext_content_security_policy.html
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/webextensions/test/mochitest/test_ext_content_security_policy.html')
-rw-r--r--toolkit/components/webextensions/test/mochitest/test_ext_content_security_policy.html162
1 files changed, 162 insertions, 0 deletions
diff --git a/toolkit/components/webextensions/test/mochitest/test_ext_content_security_policy.html b/toolkit/components/webextensions/test/mochitest/test_ext_content_security_policy.html
new file mode 100644
index 000000000..a36f29563
--- /dev/null
+++ b/toolkit/components/webextensions/test/mochitest/test_ext_content_security_policy.html
@@ -0,0 +1,162 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>WebExtension CSP test</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script type="text/javascript" src="head.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="text/javascript">
+"use strict";
+
+/**
+ * Tests that content security policies for an add-on are actually applied to *
+ * documents that belong to it. This tests both the base policies and add-on
+ * specific policies, and ensures that the parsed policies applied to the
+ * document's principal match what was specified in the policy string.
+ *
+ * @param {object} [customCSP]
+ */
+function* testPolicy(customCSP = null) {
+ let baseURL;
+
+ let baseCSP = {
+ "object-src": ["blob:", "filesystem:", "https://*", "moz-extension:", "'self'"],
+ "script-src": ["'unsafe-eval'", "'unsafe-inline'", "blob:", "filesystem:", "https://*", "moz-extension:", "'self'"],
+ };
+
+ let addonCSP = {
+ "object-src": ["'self'"],
+ "script-src": ["'self'"],
+ };
+
+ let content_security_policy = null;
+
+ if (customCSP) {
+ for (let key of Object.keys(customCSP)) {
+ addonCSP[key] = customCSP[key].split(/\s+/);
+ }
+
+ content_security_policy = Object.keys(customCSP)
+ .map(key => `${key} ${customCSP[key]}`)
+ .join("; ");
+ }
+
+
+ function filterSelf(sources) {
+ return sources.map(src => src == "'self'" ? baseURL : src);
+ }
+
+ function checkSource(name, policy, expected) {
+ is(JSON.stringify(policy[name].sort()),
+ JSON.stringify(filterSelf(expected[name]).sort()),
+ `Expected value for ${name}`);
+ }
+
+ function checkCSP(csp, location) {
+ let policies = csp["csp-policies"];
+
+ info(`Base policy for ${location}`);
+
+ is(policies[0]["report-only"], false, "Policy is not report-only");
+ checkSource("object-src", policies[0], baseCSP);
+ checkSource("script-src", policies[0], baseCSP);
+
+ info(`Add-on policy for ${location}`);
+
+ is(policies[1]["report-only"], false, "Policy is not report-only");
+ checkSource("object-src", policies[1], addonCSP);
+ checkSource("script-src", policies[1], addonCSP);
+ }
+
+
+ function getCSP(window) {
+ let {cspJSON} = SpecialPowers.Cu.getObjectPrincipal(window);
+ return JSON.parse(cspJSON);
+ }
+
+ function background(getCSPFn) {
+ browser.test.sendMessage("base-url", browser.extension.getURL("").replace(/\/$/, ""));
+
+ browser.test.sendMessage("background-csp", getCSPFn(window));
+ }
+
+ function tabScript(getCSPFn) {
+ browser.test.sendMessage("tab-csp", getCSPFn(window));
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background: `(${background})(${getCSP})`,
+
+ files: {
+ "tab.html": `<html><head><meta charset="utf-8">
+ <script src="tab.js"></${"script"}></head></html>`,
+
+ "tab.js": `(${tabScript})(${getCSP})`,
+
+ "content.html": `<html><head><meta charset="utf-8"></head></html>`,
+ },
+
+ manifest: {
+ content_security_policy,
+
+ web_accessible_resources: ["content.html", "tab.html"],
+ },
+ });
+
+
+ info(`Testing CSP for policy: ${content_security_policy}`);
+
+ yield extension.startup();
+
+ baseURL = yield extension.awaitMessage("base-url");
+
+
+ let win1 = window.open(`${baseURL}/tab.html`);
+
+ let frame = document.createElement("iframe");
+ frame.src = `${baseURL}/content.html`;
+ document.body.appendChild(frame);
+
+ yield new Promise(resolve => {
+ frame.onload = resolve;
+ });
+
+
+ let backgroundCSP = yield extension.awaitMessage("background-csp");
+ checkCSP(backgroundCSP, "background page");
+
+ let tabCSP = yield extension.awaitMessage("tab-csp");
+ checkCSP(tabCSP, "tab page");
+
+ let contentCSP = getCSP(frame.contentWindow);
+ checkCSP(contentCSP, "content frame");
+
+
+ win1.close();
+ frame.remove();
+
+ yield extension.unload();
+}
+
+add_task(function* testCSP() {
+ yield testPolicy(null);
+
+ let hash = "'sha256-NjZhMDQ1YjQ1MjEwMmM1OWQ4NDBlYzA5N2Q1OWQ5NDY3ZTEzYTNmMzRmNjQ5NGU1MzlmZmQzMmMxYmIzNWYxOCAgLQo='";
+
+ yield testPolicy({
+ "object-src": "'self' https://*.example.com",
+ "script-src": `'self' https://*.example.com 'unsafe-eval' ${hash}`,
+ });
+
+ yield testPolicy({
+ "object-src": "'none'",
+ "script-src": `'self'`,
+ });
+});
+</script>
+</body>