summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/content-security-policy/embedded-enforcement/support
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/embedded-enforcement/support')
-rw-r--r--testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-allow-csp-from.py43
-rw-r--r--testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-policy-multiple.py25
-rw-r--r--testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-required-csp.py47
-rw-r--r--testing/web-platform/tests/content-security-policy/embedded-enforcement/support/embed-img-and-message-top.html14
-rw-r--r--testing/web-platform/tests/content-security-policy/embedded-enforcement/support/executor.html3
-rw-r--r--testing/web-platform/tests/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js170
6 files changed, 302 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-allow-csp-from.py b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-allow-csp-from.py
new file mode 100644
index 0000000000..3a91437967
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-allow-csp-from.py
@@ -0,0 +1,43 @@
+import json
+def main(request, response):
+ headers = [(b"Content-Type", b"text/html")]
+ if b"allow_csp_from" in request.GET:
+ headers.append((b"Allow-CSP-From", request.GET[b"allow_csp_from"]))
+ message = request.GET[b"id"]
+ return headers, b'''
+<!DOCTYPE html>
+<html>
+<head>
+ <title>This page enforces embedder's policies</title>
+ <script nonce="123">
+ document.addEventListener("securitypolicyviolation", function(e) {
+ var response = {};
+ response["id"] = "%s";
+ response["securitypolicyviolation"] = true;
+ response["blockedURI"] = e.blockedURI;
+ response["lineNumber"] = e.lineNumber;
+ window.top.postMessage(response, '*');
+ });
+ </script>
+</head>
+<body>
+ <script nonce="123">
+ let img = document.createElement('img');
+ img.src = "../../support/pass.png";
+ img.onload = function() { window.top.postMessage("img loaded", '*'); }
+ document.body.appendChild(img);
+ </script>
+ <style>
+ body {
+ background-color: maroon;
+ }
+ </style>
+ <script nonce="abc">
+ var response = {};
+ response["id"] = "%s";
+ response["loaded"] = true;
+ window.top.postMessage(response, '*');
+ </script>
+</body>
+</html>
+''' % (message, message)
diff --git a/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-policy-multiple.py b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-policy-multiple.py
new file mode 100644
index 0000000000..b91bf0d5ea
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-policy-multiple.py
@@ -0,0 +1,25 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/html")]
+ if b"policy" in request.GET:
+ headers.append((b"Content-Security-Policy", request.GET[b"policy"]))
+ if b"policy2" in request.GET:
+ headers.append((b"Content-Security-Policy", request.GET[b"policy2"]))
+ if b"policy3" in request.GET:
+ headers.append((b"Content-Security-Policy", request.GET[b"policy3"]))
+ message = request.GET[b"id"]
+ return headers, b'''
+<!DOCTYPE html>
+<html>
+<head>
+ <title>This page sets given CSP upon itself.</title>
+</head>
+<body>
+ <script nonce="abc">
+ var response = {};
+ response["id"] = "%s";
+ response["loaded"] = true;
+ window.top.postMessage(response, '*');
+ </script>
+</body>
+</html>
+''' % (message)
diff --git a/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-required-csp.py b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-required-csp.py
new file mode 100644
index 0000000000..b704dfe92f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/echo-required-csp.py
@@ -0,0 +1,47 @@
+import json
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ message = {}
+
+ header = request.headers.get(b"Test-Header-Injection");
+ message[u'test_header_injection'] = isomorphic_decode(header) if header else None
+
+ header = request.headers.get(b"Sec-Required-CSP");
+ message[u'required_csp'] = isomorphic_decode(header) if header else None
+
+ second_level_iframe_code = u""
+ if b"include_second_level_iframe" in request.GET:
+ if b"second_level_iframe_csp" in request.GET and request.GET[b"second_level_iframe_csp"] != b"":
+ second_level_iframe_code = u'''<script>
+ var i2 = document.createElement('iframe');
+ i2.src = 'echo-required-csp.py';
+ i2.csp = "{0}";
+ document.body.appendChild(i2);
+ </script>'''.format(isomorphic_decode(request.GET[b"second_level_iframe_csp"]))
+ else:
+ second_level_iframe_code = u'''<script>
+ var i2 = document.createElement('iframe');
+ i2.src = 'echo-required-csp.py';
+ document.body.appendChild(i2);
+ </script>'''
+
+ return [(b"Content-Type", b"text/html"), (b"Allow-CSP-From", b"*")], u'''
+<!DOCTYPE html>
+<html>
+<head>
+ <!--{2}-->
+ <script>
+ window.addEventListener('message', function(e) {{
+ window.parent.postMessage(e.data, '*');
+ }});
+
+ window.parent.postMessage({0}, '*');
+ </script>
+</head>
+<body>
+{1}
+</body>
+</html>
+'''.format(json.dumps(message), second_level_iframe_code, str(request.headers))
diff --git a/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/embed-img-and-message-top.html b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/embed-img-and-message-top.html
new file mode 100644
index 0000000000..ab0e22d82f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/embed-img-and-message-top.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <script>
+ function addImage() {
+ let img = document.createElement('img');
+ img.onload = () => top.postMessage('img loaded', '*');
+ img.onerror = () => top.postMessage('img blocked', '*');
+ img.src = '/content-security-policy/support/pass.png';
+ document.body.appendChild(img);
+ }
+ </script>
+ <body onpageshow="addImage();">
+ </body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/executor.html b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/executor.html
new file mode 100644
index 0000000000..dc277a6ef0
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/executor.html
@@ -0,0 +1,3 @@
+<script>
+ window.onmessage = event => eval(event.data);
+</script>
diff --git a/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js
new file mode 100644
index 0000000000..7d2307ebbc
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js
@@ -0,0 +1,170 @@
+const Host = {
+ SAME_ORIGIN: "same-origin",
+ CROSS_ORIGIN: "cross-origin",
+};
+
+const PolicyHeader = {
+ CSP: "echo-policy.py?policy=",
+ CSP_MULTIPLE: "echo-policy-multiple.py",
+ REQUIRED_CSP: "echo-required-csp.py",
+ ALLOW_CSP_FROM: "echo-allow-csp-from.py",
+};
+
+const IframeLoad = {
+ EXPECT_BLOCK: true,
+ EXPECT_LOAD: false,
+};
+
+function getOrigin() {
+ var url = new URL("http://{{host}}:{{ports[http][0]}}/");
+ return url.origin;
+}
+
+function getCrossOrigin() {
+ var url = new URL("http://{{domains[天気の良い日]}}:{{ports[http][0]}}/");
+ return url.toString();
+}
+
+function getSecureCrossOrigin() {
+ // Since wptserve spins up servers on non-default port, 'self' matches
+ // http://[host]:[specified-port] and https://[host]:[specified-port], but not
+ // https://[host]:[https-port]. So, we use the http port for this https origin
+ // in order to verify that a secure variant of a non-secure URL matches 'self'.
+ var url = new URL("https://{{domains[天気の良い日]}}:{{ports[http][0]}}");
+ return url.toString();
+}
+
+function generateURL(host, path, include_second_level_iframe, second_level_iframe_csp) {
+ var url = new URL("http://{{host}}:{{ports[http][0]}}/content-security-policy/embedded-enforcement/support/");
+ url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}";
+ url.pathname += path;
+ if (include_second_level_iframe) {
+ url.searchParams.append("include_second_level_iframe", "");
+ if (second_level_iframe_csp)
+ url.searchParams.append("second_level_iframe_csp", second_level_iframe_csp);
+ }
+
+ return url;
+}
+
+function generateURLString(host, path) {
+ return generateURL(host, path, false, "").toString();
+}
+
+function generateURLStringWithSecondIframeParams(host, path, second_level_iframe_csp) {
+ return generateURL(host, path, true, second_level_iframe_csp).toString();
+}
+
+function generateRedirect(host, target) {
+ var url = new URL("http://{{host}}:{{ports[http][0]}}/common/redirect.py?location=" +
+ encodeURIComponent(target));
+ url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}";
+
+ return url.toString();
+}
+
+function generateUrlWithPolicies(host, policy) {
+ var url = generateURL(host, PolicyHeader.CSP_MULTIPLE);
+ if (policy != null)
+ url.searchParams.append("policy", policy);
+ return url;
+}
+
+function generateUrlWithAllowCSPFrom(host, allowCspFrom) {
+ var url = generateURL(host, PolicyHeader.ALLOW_CSP_FROM);
+ if (allowCspFrom != null)
+ url.searchParams.append("allow_csp_from", allowCspFrom);
+ return url;
+}
+
+function assert_required_csp(t, url, csp, expected) {
+ var i = document.createElement('iframe');
+ if(csp)
+ i.csp = csp;
+ i.src = url;
+
+ window.addEventListener('message', t.step_func(e => {
+ if (e.source != i.contentWindow || !('required_csp' in e.data))
+ return;
+
+ if (expected.indexOf(e.data['required_csp']) == -1)
+ assert_unreached('Child iframes have unexpected csp:"' + e.data['required_csp'] + '"');
+
+ expected.splice(expected.indexOf(e.data['required_csp']), 1);
+
+ if (e.data['test_header_injection'] != null)
+ assert_unreached('HTTP header injection was successful');
+
+ if (expected.length == 0)
+ t.done();
+ }));
+
+ document.body.appendChild(i);
+}
+
+function assert_iframe_with_csp(t, url, csp, shouldBlock, urlId, blockedURI,
+ checkImageLoaded) {
+ const i = document.createElement('iframe');
+ url.searchParams.append("id", urlId);
+ i.src = url.toString();
+ if (csp != null)
+ i.csp = csp;
+
+ var loaded = {};
+ var onLoadReceived = {};
+ window.addEventListener("message", function (e) {
+ if (e.source != i.contentWindow)
+ return;
+ if (e.data["loaded"])
+ loaded[e.data["id"]] = true;
+ });
+
+ if (shouldBlock) {
+ // Assert iframe does not load and is inaccessible.
+ window.onmessage = t.step_func(function(e) {
+ if (e.source != i.contentWindow)
+ return;
+ assert_unreached('No message should be sent from the frame.');
+ });
+ i.onload = t.step_func(function () {
+ // Delay the check until after the postMessage has a chance to execute.
+ setTimeout(t.step_func_done(function () {
+ assert_equals(loaded[urlId], undefined);
+ }), 500);
+ assert_throws_dom("SecurityError", () => {
+ var x = i.contentWindow.location.href;
+ });
+ });
+ } else if (blockedURI) {
+ // Assert iframe loads with an expected violation.
+ window.addEventListener('message', t.step_func(e => {
+ if (e.source != i.contentWindow)
+ return;
+ if (!e.data.securitypolicyviolation)
+ return;
+ assert_equals(e.data["blockedURI"], blockedURI);
+ t.done();
+ }));
+ } else {
+ // Assert iframe loads. Wait for the load event, the postMessage from the
+ // script and the img load event.
+ let img_loaded = !checkImageLoaded;
+ window.addEventListener('message', t.step_func(e => {
+ if (e.source != i.contentWindow)
+ return;
+ if (e.data === "img loaded")
+ img_loaded = true;
+
+ if (loaded[urlId] && onLoadReceived[urlId] && img_loaded) {
+ t.done();
+ }
+ }));
+ i.onload = t.step_func(function () {
+ onLoadReceived[urlId] = true;
+ if (loaded[urlId] && onLoadReceived[urlId] && img_loaded) {
+ t.done();
+ }
+ });
+ }
+ document.body.appendChild(i);
+}