diff options
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js')
-rw-r--r-- | testing/web-platform/tests/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js | 170 |
1 files changed, 170 insertions, 0 deletions
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); +} |