summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/content-security-policy/reporting
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/reporting')
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html19
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html.sub.headers8
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html107
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html34
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html.sub.headers7
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html.sub.headers7
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html.sub.headers7
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-clips-sample.https.html45
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html37
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors-with-x-frame-options.sub.html12
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors.sub.html12
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html19
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html46
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html.sub.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers4
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html11
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html51
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-preload-and-consume.https.html24
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html34
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-strips-fragment.html23
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html18
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-from-child-frame.html23
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html15
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html.sub.headers7
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html16
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html.sub.headers7
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html18
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html12
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/not-embeddable-frame.py10
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html30
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/redirect-throw-function.sub.py10
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/set-cookie.py33
-rw-r--r--testing/web-platform/tests/content-security-policy/reporting/support/throw-function.js9
54 files changed, 924 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html b/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html
new file mode 100644
index 0000000000..c28e9ae44a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>When multiple report-uri endpoints for multiple policies are specified, each gets a report</title>
+ <!-- CSP headers
+Content-Security-Policy-Report-Only: img-src http://* https://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+
+Content-Security-Policy-Report-Only: img-src http://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+-->
+</head>
+<body>
+ <img src="ftp://blah.test" />
+
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A%20https%3A%2F%2F%2A&testName=1-Violation%20report%20status%20OK'></script>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A&reportCookieName=multiple-report-policies-2&testName=2-Violation%20report%20status%20OK'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html.sub.headers
new file mode 100644
index 0000000000..485b6832e7
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html.sub.headers
@@ -0,0 +1,8 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: multiple-report-policies={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy-Report-Only: img-src http://* https://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+Set-Cookie: multiple-report-policies-2={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy-Report-Only: img-src http://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html b/testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html
new file mode 100644
index 0000000000..9815cdfa19
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<head>
+ <title>Check for post-redirect leak from StackTrace.</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/common/utils.js"></script>
+</head>
+<body>
+<script>
+
+const CROSS_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
+const CROSS_SITE = get_host_info().HTTPS_NOTSAMESITE_ORIGIN;
+
+const blank_path = "/common/blank.html"
+const redirect = url =>
+ `/content-security-policy/reporting/support/redirect-throw-function.sub.py?token=${token()}`;
+
+const script_path = "/content-security-policy/reporting/support/throw-function.js"
+const script_ref = "#ref"
+const script_attribute = "?secret=1234";
+
+promise_setup(async () => {
+ await new Promise(r => window.addEventListener("DOMContentLoaded", r));
+});
+
+let loadScript = origin => {
+ let script = document.createElement("script");
+ script.src = origin +
+ redirect(origin + script_path + script_attribute + script_ref);
+ let script_loaded = new Promise(r => script.onload = r);
+ document.head.appendChild(script);
+ return script_loaded;
+}
+
+// Note: .stack properties on errors are unspecified, but are present in most
+// browsers, most of the time. https://github.com/tc39/proposal-error-stacks
+// tracks standardizing them. Tests will pass automatically if the .stack
+// property isn't present.
+let getStack = async (origin) => {
+ await loadScript(origin);
+ try {
+ throw_function();
+ } catch (error) {
+ if (error.stack)
+ return error.stack.toString();
+ }
+ return "";
+};
+
+promise_test(async test => {
+ let data = await getStack(CROSS_ORIGIN);
+ assert_false(data.includes(script_ref), "Ref not leaked");
+ assert_false(data.includes(script_attribute), "Attribute not leaked");
+ assert_false(data.includes(script_path), "Path not leaked");
+}, "StackTrace do not leak cross-origin post-redirect URL");
+
+promise_test(async test => {
+ let data = await getStack(CROSS_SITE);
+ assert_false(data.includes(script_ref), "Ref not leaked");
+ assert_false(data.includes(script_attribute), "Attribute not leaked");
+ assert_false(data.includes(script_path), "Path not leaked");
+}, "StackTrace do not leak cross-site post-redirect URL");
+
+let getCspReport = async (origin) => {
+ // A promise to a future CSP violation.
+ let violation = new Promise(resolve => {
+ const observer = new ReportingObserver(reports => {
+ observer.disconnect();
+ resolve(JSON.stringify(reports));
+ });
+ observer.observe();
+ });
+
+ // This will be blocked by CSP:
+ let script = document.createElement("script");
+ script.src = origin +
+ redirect(origin + script_path + script_attribute + script_ref);
+ script.onload = () => { load_image(); };
+ document.head.appendChild(script);
+
+ return await violation;
+};
+
+// This block is needed to reproduce https://crbug.com/1074316. Without, the
+// next test passes. There is no 'source-file' found in report.
+// TODO(arthursonzogni): Investigate more. Find why this has side effects.
+promise_setup(async test => {
+ await getCspReport(CROSS_ORIGIN);
+}, "prewarm the cache");
+
+promise_test(async test => {
+ let data = await getCspReport(CROSS_ORIGIN);
+ assert_false(data.includes(script_ref), "Ref not leaked");
+ assert_false(data.includes(script_attribute), "Attribute not leaked");
+ assert_false(data.includes(script_path), "Path not leaked");
+}, "CSP report do not leak cross-origin post-redirect URL");
+
+promise_test(async test => {
+ let data = await getCspReport(CROSS_SITE);
+ assert_false(data.includes(script_ref), "Ref not leaked");
+ assert_false(data.includes(script_attribute), "Attribute not leaked");
+ assert_false(data.includes(script_path), "Path not leaked");
+}, "CSP report do not leak cross-site post-redirect URL");
+
+</script>
+</body>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html.headers b/testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html.headers
new file mode 100644
index 0000000000..644ed867f3
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html.headers
@@ -0,0 +1 @@
+Content-Security-Policy-Report-Only: img-src 'none'; report-uri /endpoint
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html b/testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html
new file mode 100644
index 0000000000..01f60800ed
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Reporting and enforcing policies can be different</title>
+ <!-- CSP headers
+Content-Security-Policy: img-src 'none'; style-src *; script-src 'self' 'unsafe-inline'
+
+Content-Security-Policy-Report-Only: img-src *; style-src 'none'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+-->
+</head>
+<body>
+ <script>
+ var img_test = async_test("The image should be blocked");
+ var sheet_test = async_test("The stylesheet should load");
+ <!-- This image should be blocked, but should not generate a report-->
+ var i = document.createElement('img');
+ i.onerror = img_test.step_func_done();
+ i.onload = img_test.unreached_func("Should not have loaded the img");
+ i.src = "../support/fail.png";
+ document.body.appendChild(i);
+ <!-- This font should be loaded but should generate a report-->
+ var s = document.createElement('link');
+ s.onerror = sheet_test.unreached_func("Should have loaded the font");
+ s.onload = sheet_test.step_func_done();
+ s.type = "text/css";
+ s.rel="stylesheet";
+ s.href = "../support/fonts.css";
+ document.body.appendChild(s);
+ </script>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=style-src%20%27none%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html.sub.headers
new file mode 100644
index 0000000000..4d7e6f191a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-and-enforce.html.sub.headers
@@ -0,0 +1,7 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-and-enforce={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: img-src 'none'; style-src *; script-src 'self' 'unsafe-inline'
+Content-Security-Policy-Report-Only: img-src *; style-src 'none'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html
new file mode 100644
index 0000000000..681694f691
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Data-uri images are reported correctly</title>
+ <!-- CSP headers
+Content-Security-Policy: img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+-->
+</head>
+<body>
+ <img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html.sub.headers
new file mode 100644
index 0000000000..22c0494019
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-data-uri.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-blocked-data-uri={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html
new file mode 100644
index 0000000000..a2966dbafb
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Cross-origin images are reported correctly</title>
+ <!-- CSP headers
+Content-Security-Policy: script-src 'self' 'unsafe-inline'
+Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID=$id
+-->
+</head>
+<body>
+ <img src="http://{{domains[www1]}}:{{ports[http][0]}}/content-security-policy/support/pass.png">
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html.sub.headers
new file mode 100644
index 0000000000..02ebafeefe
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri-cross-origin.sub.html.sub.headers
@@ -0,0 +1,7 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-blocked-uri-cross-origin={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: script-src 'self' 'unsafe-inline'
+Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html
new file mode 100644
index 0000000000..1cfff902a2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Blocked relative images are reported correctly</title>
+ <!-- CSP headers
+Content-Security-Policy: script-src 'self' 'unsafe-inline'
+Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+-->
+</head>
+<body>
+ <img src="../support/pass.png">
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html.sub.headers
new file mode 100644
index 0000000000..8fb2f58aba
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-blocked-uri.html.sub.headers
@@ -0,0 +1,7 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-blocked-uri={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: script-src 'self' 'unsafe-inline'
+Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-clips-sample.https.html b/testing/web-platform/tests/content-security-policy/reporting/report-clips-sample.https.html
new file mode 100644
index 0000000000..696a27ba75
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-clips-sample.https.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/content-security-policy/support/testharness-helper.js"></script>
+ <meta http-equiv="Content-Security-Policy"
+ content="require-trusted-types-for 'script'; trusted-types default">
+</head>
+<body>
+ <script>
+ promise_test(t => {
+ let evil = false;
+ assert_throws_js(EvalError, _ => {
+ eval("evil = '1234567890123456789012345678901234567890';");
+ });
+ assert_false(evil);
+ return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => {
+ assert_equals(e.sample, "eval|evil = '12345678901234567890123456789012");
+ }));
+ }, "Unsafe eval violation sample is clipped to 40 characters.");
+
+ promise_test(t => {
+ assert_throws_js(EvalError, _ => {
+ new Function("a", "b", "return '1234567890123456789012345678901234567890';");
+ });
+ return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => {
+ assert_equals(e.sample.replace(/\n/g, ""),
+ "Function|(a,b) {return '12345678901234567890123");
+ }));
+ }, "Function constructor - the other kind of eval - is clipped.");
+
+ promise_test(t => {
+ const a = document.createElement("a");
+ assert_throws_js(TypeError, _ => {
+ a.innerHTML = "1234567890123456789012345678901234567890xxxx";
+ });
+ assert_equals(a.innerHTML, "");
+ return waitUntilCSPEventForTrustedTypes(t).then(t.step_func_done(e => {
+ assert_equals(e.sample, "Element innerHTML|1234567890123456789012345678901234567890");
+ }));
+ }, "Trusted Types violation sample is clipped to 40 characters excluded the sink name.");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html b/testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html
new file mode 100644
index 0000000000..b8203e9d30
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Cookies are not sent on cross origin violation reports</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- CSP headers
+ Content-Security-Policy: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri http://{{domains[www1]}}:{{ports[http][0]}}/reporting/resources/report.py?op=put&reportID=$id
+ -->
+</head>
+<body>
+<script>
+ promise_test(function(test) {
+ const path = encodeURIComponent("{{domains[www1]}}:{{ports[http][0]}}/");
+ return fetch(
+ "/cookies/resources/set-cookie.py?name=cspViolationReportCookie1&path=" + path,
+ {mode: 'no-cors', credentials: 'include'})
+ .then(() => {
+ test.add_cleanup(() => {
+ return fetch("/cookies/resources/set.py?cspViolationReportCookie1=; path=" + path + "; expires=Thu, 01 Jan 1970 00:00:01 GMT");
+ });
+
+ // This image will generate a CSP violation report.
+ const img = new Image();
+ img.onerror = test.step_func_done();
+ img.onload = test.unreached_func("Should not have loaded the image");
+
+ img.src = "../support/fail.png";
+ document.body.appendChild(img);
+ });
+ }, "Image should not load");
+</script>
+<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27&noCookies=true'></script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html.sub.headers
new file mode 100644
index 0000000000..f65bd9ebf3
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-cross-origin-no-cookies.sub.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-cross-origin-no-cookies={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri http://{{domains[www1]}}:{{ports[http][0]}}/reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors-with-x-frame-options.sub.html b/testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors-with-x-frame-options.sub.html
new file mode 100644
index 0000000000..0c58a5efd5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors-with-x-frame-options.sub.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Reporting works with report-only frame-ancestors even if frame is blocked by X-Frame-Options</title>
+</head>
+<body>
+ <iframe src="./support/not-embeddable-frame.py?reportID={{$id:uuid()}}&reportOnly=true&xFrameOptions=DENY"></iframe>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-ancestors&reportID={{$id}}'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors.sub.html b/testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors.sub.html
new file mode 100644
index 0000000000..cd7bbcb973
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-frame-ancestors.sub.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Reporting works with frame-ancestors</title>
+</head>
+<body>
+ <iframe src="./support/not-embeddable-frame.py?reportID={{$id:uuid()}}"></iframe>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-ancestors&reportID={{$id}}'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html
new file mode 100644
index 0000000000..e64269c2de
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Test multiple violations cause multiple reports</title>
+ <!-- CSP headers
+ Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+ <img src="../support/pass.png">
+ <img src="../support/pass2.png">
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27&reportCount=2'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html.sub.headers
new file mode 100644
index 0000000000..f86f84b8b2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-01.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-multiple-violations-01={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html
new file mode 100644
index 0000000000..cc64f151a3
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>This tests that multiple violations on a page trigger multiple reports
+ if and only if the violations are distinct.</title>
+ <!-- CSP headers
+ Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+ <script>
+ for (var i = 0; i<5; i++)
+ setTimeout("document.body.innerHTML += ('<p>PASS: setTimeout #" + i + " executed.');", 0);
+ </script>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27unsafe-inline%27%20%27self%27&reportCount=1'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html.sub.headers
new file mode 100644
index 0000000000..e94e0dfa60
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-multiple-violations-02.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-multiple-violations-02={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html b/testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html
new file mode 100644
index 0000000000..4df9865d2c
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Report-only policy not allowed in meta tag</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- CSP headers
+ Content-Security-Policy: script-src 'unsafe-inline' 'self'
+ -->
+ <!-- since we try to set the report-uri in the meta tag, we have to set the cookie with the reportID in here instead of in the headers file -->
+ <meta http-equiv="Content-Security-Policy-Report-Only" content="img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id:uuid()}}">
+</head>
+<body>
+ <script>
+ var test = async_test("Image should load");
+
+ <!-- Set cookie for checking if the report exists
+ -->
+ fetch(
+ "support/set-cookie.py?name=report-only-in-meta&value={{$id}}&path=" + encodeURIComponent("/content-security-policy/reporting/"),
+ {mode: 'no-cors', credentials: 'include'})
+ .then(() => {
+ const img = new Image();
+ img.onload = test.step_func_done();
+ img.onerror = test.unreached_func("Should have loaded the image");
+
+ img.src = "../support/pass.png";
+ document.body.appendChild(img);
+
+ <!-- this needs to be done after setting the cookie so we do it here -->
+ const script = document.createElement('script');
+ script.async = true;
+ script.defer = true;
+ script.src = '../support/checkReport.sub.js?reportExists=false'
+ document.body.appendChild(script);
+
+ // Immediately declare a test so that the harness does not infer
+ // completion if the image loads before the script.
+ var checkReportTest = async_test("checkReport tests loaded");
+ script.onload = checkReportTest.step_func_done();
+ script.onerror = checkReportTest.unreached_func();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html.sub.headers
new file mode 100644
index 0000000000..b56292b470
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-only-in-meta.sub.html.sub.headers
@@ -0,0 +1,5 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Content-Security-Policy: script-src 'unsafe-inline' 'self'
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html b/testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html
new file mode 100644
index 0000000000..757db4f37b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script nonce='abc' src="/resources/testharness.js"></script>
+ <script nonce='abc' src="/resources/testharnessreport.js"></script>
+ <!-- CSP headers
+Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'nonce-abc'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+-->
+</head>
+<body>
+ <script nonce='abc'>
+ var t = async_test("Eval is allowed because the CSP is report-only");
+
+ var t_spv = async_test("SPV event is still raised");
+ t_spv.step_timeout(t_spv.unreached_func("SPV event has not been received"), 3000);
+ document.addEventListener('securitypolicyviolation', t_spv.step_func(e => {
+ assert_equals(e.violatedDirective, "script-src");
+ assert_equals(e.blockedURI, "eval");
+ t_spv.done();
+ }));
+
+ try {
+ eval("t.done()");
+ } catch {
+ t.step(t.unreached_func("The eval should have executed succesfully"));
+ t_spv.step(t_spv.unreached_func("The eval execution should have triggered a securitypolicyviolation event"));
+ }
+ </script>
+ <script nonce='abc' async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27unsafe-inline%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers
new file mode 100644
index 0000000000..5ca4a65261
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-only-unsafe-eval.html.sub.headers
@@ -0,0 +1,4 @@
+Cache-Control: no-store, no-cache, must-revalidate
+Pragma: no-cache
+Set-Cookie: report-only-unsafe-eval={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'nonce-abc'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html b/testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html
new file mode 100644
index 0000000000..67db730631
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script async defer src='../support/checkReport.sub.js?reportField=blocked-uri&reportValue={{location[scheme]}}%3A%2F%2F{{location[host]}}/common/redirect.py%3Flocation%3Dhttp%253A%252F%252F{{hosts[][]}}%253A{{ports[http][0]}}%252Fcontent-security-policy%252Fsupport%252Ffail.html%253Ft%253D1'></script>
+<iframe src='{{location[scheme]}}://{{location[host]}}/common/redirect.py?location=http%3A%2F%2F{{hosts[][]}}%3A{{ports[http][0]}}%2Fcontent-security-policy%2Fsupport%2Ffail.html%3Ft%3D1' style='display: none;'>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html.sub.headers
new file mode 100644
index 0000000000..50b5438c4b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-original-url-on-mixed-content-frame={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: block-all-mixed-content; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html b/testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html
new file mode 100644
index 0000000000..f95f7e3e6b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- CSP headers
+ Content-Security-Policy: img-src {{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}; script-src 'unsafe-inline' 'self'; report-uri /reporting/resources/report.py?op=put&reportID=$id
+ -->
+</head>
+<body>
+<script>
+function createListener(expectedURL, test) {
+ var listener = test.step_func(e => {
+ if (e.blockedURI == expectedURL) {
+ document.removeEventListener('securitypolicyviolation', listener);
+ test.done();
+ }
+ });
+ document.addEventListener('securitypolicyviolation', listener);
+}
+
+async_test(t => {
+ var i = document.createElement('img');
+ createListener("{{location[scheme]}}://{{location[host]}}/content-security-policy/support/fail.png?t=1", t);
+ i.src = "{{location[scheme]}}://{{location[host]}}/content-security-policy/support/fail.png?t=1";
+}, "Direct block, same-origin = full URL in report");
+
+async_test(t => {
+ var i = document.createElement('img');
+ createListener("{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/content-security-policy/support/fail.png?t=2", t);
+ i.src = "{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/content-security-policy/support/fail.png?t=2";
+}, "Direct block, cross-origin = full URL in report");
+
+async_test(t => {
+ var i = document.createElement('img');
+ var url = "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/common/redirect.py?location=" + encodeURIComponent("{{location[scheme]}}://{{location[host]}}/content-security-policy/support/fail.png?t=3");
+ createListener(url, t);
+ i.src = url;
+}, "Block after redirect, same-origin = original URL in report");
+
+async_test(t => {
+ var i = document.createElement('img');
+ var url = "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/common/redirect.py?location=" + encodeURIComponent("{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/content-security-policy/support/fail.png?t=4");
+ createListener(url, t);
+ i.src = url;
+}, "Block after redirect, cross-origin = original URL in report");
+</script>
+
+<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src {{location[scheme]}}%3A%2F%2F{{domains[www1]}}%3A{{ports[http][0]}}'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html.sub.headers
new file mode 100644
index 0000000000..b695417aef
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-original-url.sub.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-original-url={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: img-src {{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}; script-src 'unsafe-inline' 'self'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-preload-and-consume.https.html b/testing/web-platform/tests/content-security-policy/reporting/report-preload-and-consume.https.html
new file mode 100644
index 0000000000..771434f673
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-preload-and-consume.https.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test that reports are sent with credentials to same-origin endpoints</title>
+ <script src="/common/utils.js"></script>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ <script src='/reporting/resources/report-helper.js'></script>
+</head>
+<body>
+ <script>
+ const endpoint = '/reporting/resources/report.py';
+
+ promise_test(async t => {
+ const uid = token();
+ const win = window.open(`./support/preload-csp-report.https.sub.html?uid=${uid}`);
+ t.add_cleanup(() => win.close());
+ const reports = await pollReports(endpoint, uid);
+ const failures = reports.filter(r => r['csp-report']['blocked-uri'].endsWith('fail.png'));
+ assert_equals(failures.length, 2);
+ }, "Reporting endpoints received credentials.");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html b/testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html
new file mode 100644
index 0000000000..aa2ec6bd9d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Cookies are sent on same origin violation reports</title>
+ <!-- CSP headers
+ Content-Security-Policy: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+<script>
+ var test = async_test("Image should not load");
+ fetch(
+ "/cookies/resources/set-cookie.py?name=cspViolationReportCookie2&path=" + encodeURIComponent("/"),
+ {mode: 'no-cors', credentials: 'include'})
+ .then(() => {
+ test.add_cleanup(() => {
+ document.cookie = "cspViolationReportCookie2=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT";
+ });
+
+ // This image will generate a CSP violation report.
+ const img = new Image();
+ img.onerror = test.step_func_done();
+ img.onload = test.unreached_func("Should not have loaded the image");
+
+ img.src = "../support/fail.png";
+ document.body.appendChild(img);
+ });
+</script>
+<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27&cookiePresent=cspViolationReportCookie2'></script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html.sub.headers
new file mode 100644
index 0000000000..23fb823730
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-same-origin-with-cookies.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-same-origin-with-cookies={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-strips-fragment.html b/testing/web-platform/tests/content-security-policy/reporting/report-strips-fragment.html
new file mode 100644
index 0000000000..4ecfa845ec
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-strips-fragment.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/content-security-policy/support/testharness-helper.js"></script>
+ <meta http-equiv="Content-Security-Policy" content="img-src 'none'">
+</head>
+<body>
+ <script>
+ async_test(t => {
+ waitUntilCSPEventForURL(t, "https://evil.com/img.png")
+ .then(t.step_func_done(e => {
+ var u = new URL(e.documentURI);
+ assert_equals(u.hash, "");
+ }));
+
+ window.location.hash = "should-not-appear-in-report";
+
+ var i = document.createElement("img");
+ i.src = "https://evil.com/img.png#boo";
+ }, "Reported document URI does not contain fragments.");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html b/testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html
new file mode 100644
index 0000000000..0143d1bc82
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Violation report is sent if violation occurs.</title>
+ <!-- CSP headers
+ Content-Security-Policy: default-src 'self'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+ <script>
+ // This script block will trigger a violation report.
+ alert('FAIL');
+ </script>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27self%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html.sub.headers
new file mode 100644
index 0000000000..9b8c3d0fdb
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-effective-directive.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-uri-effective-directive={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: default-src 'self'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-child-frame.html b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-child-frame.html
new file mode 100644
index 0000000000..1be496194b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-child-frame.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Reporting works in child iframes.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc'">
+</head>
+<body>
+ <script nonce="abc">
+ window.onmessage = function(e) {
+ if (e.data == 'cookie set') {
+ var s = document.createElement('script');
+ s.async = true;
+ s.defer = true;
+ s.src = '../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27self%27%20%27nonce-abc%27&reportCookieName=generate-csp-report';
+ document.body.appendChild(s);
+ }
+ }
+ </script>
+ <iframe src="support/generate-csp-report.html"/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html
new file mode 100644
index 0000000000..1cb5a2c659
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Violation report is sent from inline javascript.</title>
+ <!-- CSP headers
+ Content-Security-Policy: img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+ <script>
+ // This script block will trigger a violation report.
+ var i = document.createElement('img');
+ i.src = '/security/resources/abe.png';
+ document.body.appendChild(i);
+ </script>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html.sub.headers
new file mode 100644
index 0000000000..fd2913a39b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-inline-javascript.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-uri-from-inline-javascript={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html
new file mode 100644
index 0000000000..d535811125
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Violation report is sent from javascript resource.</title>
+ <!-- CSP headers
+ Content-Security-Policy: img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+ <script src="../support/inject-image.js"></script>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html.sub.headers
new file mode 100644
index 0000000000..faa23708e5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-from-javascript.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-uri-from-javascript={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: img-src 'none'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html
new file mode 100644
index 0000000000..5bbdc01a53
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Content-Security-Policy-Report-Only violation report is sent even when resource is blocked by actual policy.</title>
+ <!-- CSP headers
+ Content-Security-Policy-Report-Only: img-src http://*; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ Content-Security-Policy: img-src http://*
+ -->
+</head>
+<body>
+ <img src="ftp://blah.test" />
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html.sub.headers
new file mode 100644
index 0000000000..172c36dee0
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html.sub.headers
@@ -0,0 +1,7 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-uri-multiple-reversed={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy-Report-Only: img-src http://*; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+Content-Security-Policy: img-src http://*
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html
new file mode 100644
index 0000000000..190c9ee31e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Content-Security-Policy-Report-Only violation report is sent even when resource is blocked by actual policy.</title>
+ <!-- CSP headers
+ Content-Security-Policy: img-src http://*
+ Content-Security-Policy-Report-Only: img-src http://*; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+ <img src="ftp://blah.test" />
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html.sub.headers
new file mode 100644
index 0000000000..cf1073823d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html.sub.headers
@@ -0,0 +1,7 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-uri-multiple={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: img-src http://*
+Content-Security-Policy-Report-Only: img-src http://*; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html b/testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html
new file mode 100644
index 0000000000..406238ead7
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <title>Relative scheme URIs are accepted as the report-uri.</title>
+ <!-- CSP headers
+ Content-Security-Policy: script-src 'self'; report-uri //{{location[host]}}/reporting/resources/report.py?op=put&reportID={{$id}}
+ -->
+</head>
+<body>
+ <script>
+ // This script block will trigger a violation report.
+ alert('FAIL');
+ </script>
+ <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27self%27'></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html.sub.headers
new file mode 100644
index 0000000000..97e302a4b7
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-scheme-relative.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: report-uri-scheme-relative={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: script-src 'self'; report-uri //{{location[host]}}/reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html b/testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html
new file mode 100644
index 0000000000..c2024c0a1b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <script nonce='abc'>
+ top.postMessage('cookie set', '*');
+ </script>
+ <script>
+ // This script block will trigger a violation report.
+ alert('FAIL');
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html.sub.headers
new file mode 100644
index 0000000000..7993b3e286
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/generate-csp-report.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: generate-csp-report={{$id:uuid()}}; Path=/content-security-policy/reporting/
+Content-Security-Policy: script-src 'self' 'nonce-abc'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/not-embeddable-frame.py b/testing/web-platform/tests/content-security-policy/reporting/support/not-embeddable-frame.py
new file mode 100644
index 0000000000..9e65b42435
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/not-embeddable-frame.py
@@ -0,0 +1,10 @@
+def main(request, response):
+ headers = []
+ if request.GET.first(b'xFrameOptions', None):
+ headers.append((b'X-Frame-Options', request.GET[b'xFrameOptions']))
+
+ csp_header = b'Content-Security-Policy-Report-Only' \
+ if request.GET.first(b'reportOnly', None) == b'true' else b'Content-Security-Policy'
+ headers.append((csp_header, b"frame-ancestors 'none'; report-uri /reporting/resources/report.py?op=put&reportID=" + request.GET[b'reportID']))
+
+ return headers, b'{}'
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html b/testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html
new file mode 100644
index 0000000000..6b79414edd
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<body>
+<!-- This image will cause a CSP violation, which will trigger an immediate report -->
+<script>
+ const href = "/reporting/resources/fail.png";
+
+ window.addEventListener('load', async () => {
+ // Trigger a CSP error.
+ await new Promise(resolve => {
+ const link = document.createElement('link');
+ link.rel = 'preload';
+ link.href = href;
+ link.as = 'image';
+ document.head.appendChild(link);
+ link.addEventListener('error', resolve);
+ });
+
+ // Trigger a second CSP error by consuming.
+ await new Promise(resolve => {
+ const img = document.createElement('img');
+ img.src = href;
+ img.addEventListener('error', resolve);
+ document.body.appendChild(img);
+ });
+ });
+</script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html.sub.headers
new file mode 100644
index 0000000000..bb0506b41d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/preload-csp-report.https.sub.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: img-src none; report-uri /reporting/resources/report.py?op=put&reportID={{GET[uid]}}
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/redirect-throw-function.sub.py b/testing/web-platform/tests/content-security-policy/reporting/support/redirect-throw-function.sub.py
new file mode 100644
index 0000000000..1bc89abf71
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/redirect-throw-function.sub.py
@@ -0,0 +1,10 @@
+import re
+
+from wptserve.utils import isomorphic_encode
+
+def main(request, response):
+ response.status = 302
+ location = re.sub(b'redirect-throw-function.*',
+ b'throw-function.js?secret=1234#ref',
+ isomorphic_encode(request.url))
+ response.headers.set(b"Location", location)
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/set-cookie.py b/testing/web-platform/tests/content-security-policy/reporting/support/set-cookie.py
new file mode 100644
index 0000000000..e720c5c2cb
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/set-cookie.py
@@ -0,0 +1,33 @@
+from datetime import date
+
+def main(request, response):
+ """
+ Returns cookie name and path from query params in a Set-Cookie header.
+
+ e.g.
+
+ > GET /cookies/resources/set-cookie.py?name=match-slash&path=%2F HTTP/1.1
+ > Host: localhost:8000
+ > User-Agent: curl/7.43.0
+ > Accept: */*
+ >
+ < HTTP/1.1 200 OK
+ < Content-Type: application/json
+ < Set-Cookie: match-slash=1; Path=/; Expires=09 Jun 2021 10:18:14 GMT
+ < Server: BaseHTTP/0.3 Python/2.7.12
+ < Date: Tue, 04 Oct 2016 18:16:06 GMT
+ < Content-Length: 80
+ """
+
+ name = request.GET[b'name']
+ path = request.GET[b'path']
+ value = request.GET.first(b'value', b"1")
+ expiry_year = date.today().year + 1
+ cookie = b"%s=%s; Path=%s; Expires=09 Jun %d 10:18:14 GMT" % (name, value, path, expiry_year)
+
+ headers = [
+ (b"Content-Type", b"application/json"),
+ (b"Set-Cookie", cookie)
+ ]
+ body = b"{}"
+ return headers, body
diff --git a/testing/web-platform/tests/content-security-policy/reporting/support/throw-function.js b/testing/web-platform/tests/content-security-policy/reporting/support/throw-function.js
new file mode 100644
index 0000000000..d0e9d203dd
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/reporting/support/throw-function.js
@@ -0,0 +1,9 @@
+function throw_function() {
+ throw new Error("an error");
+}
+
+function load_image() {
+ let img = document.createElement('img');
+ document.body.append(img);
+ img.src = "/xhr/resources/img.jpg"
+}