summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/content-security-policy/script-src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/content-security-policy/script-src
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/script-src')
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/10_1_support_1.js4
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/10_1_support_2.js5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/addInlineTestsWithDOMManipulation.js28
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/buildInlineWorker.js21
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js3
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html19
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html.sub.headers2
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode.html17
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/externalScript.js1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html36
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-allowed.sub.html24
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-blocked.sub.html25
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/inlineSuccessTest.js12
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/inlineTests.js22
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/nonce-enforce-blocked.html63
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_1.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_10.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_10_1.html19
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_2.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_2_1.html21
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_3.html18
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_4.html28
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_1.html33
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_2.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html26
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html26
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-overrides-default-src.sub.html27
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html25
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html.sub.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.sub.html104
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.sub.html.sub.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html32
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html68
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html61
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html44
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html.headers6
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html38
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html52
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html32
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html32
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html76
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html.headers4
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html37
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html76
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html29
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html205
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html110
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html.headers5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker-importScripts.https.html18
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker.https.html20
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/script-src-wildcards-disallowed.html63
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-allowed.sub.html42
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-base64url-converts-to-base64.sub.html40
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked-error-event.html10
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked.sub.html72
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-case-insensitive.sub.html60
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-1.html35
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-2.html35
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-default-src.sub.html21
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-ignore-unsafeinline.sub.html56
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scripthash-unicode-normalization.sub.html72
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-allowed.sub.html68
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-and-scripthash.sub.html79
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-basic-blocked.sub.html43
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-1.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-2.html31
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-ignore-unsafeinline.sub.html74
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-redirect.sub.html62
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html43
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/simpleSourcedScript.js1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html35
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/change-scripthash-before-execute.js10
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/change-scriptnonce-before-execute.js8
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/empty.css0
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/inject-script.js5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/inline-script-should-be-blocked.js14
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/post-message.js1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js5
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js7
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js17
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js16
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js.sub.headers1
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/worker-data-set-timeout.sub.html28
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/worker-eval-blocked.sub.html38
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/worker-function-function-blocked.sub.html37
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/worker-importscripts.sub.html26
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/worker-script-src.sub.html32
-rw-r--r--testing/web-platform/tests/content-security-policy/script-src/worker-set-timeout.sub.html26
126 files changed, 3238 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/script-src/10_1_support_1.js b/testing/web-platform/tests/content-security-policy/script-src/10_1_support_1.js
new file mode 100644
index 0000000000..9bfe201711
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/10_1_support_1.js
@@ -0,0 +1,4 @@
+var dataScriptRan = false;
+
+var t_spv = async_test("Test that no report violation event was raised");
+window.addEventListener("securitypolicyviolation", t_spv.unreached_func("Should not have raised any securitypolicyviolation event")); \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/10_1_support_2.js b/testing/web-platform/tests/content-security-policy/script-src/10_1_support_2.js
new file mode 100644
index 0000000000..ff159db33c
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/10_1_support_2.js
@@ -0,0 +1,5 @@
+test(function () {
+ assert_true(dataScriptRan, "data script ran");
+ }, "Verify that data: as script src runs with this policy");
+
+t_spv.done(); \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/addInlineTestsWithDOMManipulation.js b/testing/web-platform/tests/content-security-policy/script-src/addInlineTestsWithDOMManipulation.js
new file mode 100644
index 0000000000..02c8c8cdd4
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/addInlineTestsWithDOMManipulation.js
@@ -0,0 +1,28 @@
+(function () {
+ var t_spv = async_test("Test that securitypolicyviolation event is fired");
+ var test_count = 2;
+
+ window.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src-elem");
+ if (--test_count <= 0) {
+ t_spv.done();
+ }
+ }));
+
+
+ var dmTest = async_test("DOM manipulation inline tests");
+ var attachPoint = document.getElementById('attachHere');
+ var inlineScript = document.createElement('script');
+ var scriptText = document.createTextNode('dmTest.step(function() {assert_unreached("Unsafe inline script ran - createTextNode.")});');
+
+ inlineScript.appendChild(scriptText);
+ attachPoint.appendChild(inlineScript);
+
+ document.getElementById('emptyScript').innerHTML = 'dmTest.step(function() {assert_unreached("Unsafe inline script ran - innerHTML.")});';
+ document.getElementById('emptyDiv').outerHTML = '<script id=outerHTMLScript>dmTest.step(function() {assert_unreached("Unsafe inline script ran - outerHTML.")});</script>';
+
+ document.write('<script>dmTest.step(function() {assert_unreached("Unsafe inline script ran - document.write")});</script>');
+ document.writeln('<script>dmTest.step(function() {assert_unreached("Unsafe inline script ran - document.writeln")});</script>');
+
+ dmTest.done();
+})();
diff --git a/testing/web-platform/tests/content-security-policy/script-src/buildInlineWorker.js b/testing/web-platform/tests/content-security-policy/script-src/buildInlineWorker.js
new file mode 100644
index 0000000000..8cd092147c
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/buildInlineWorker.js
@@ -0,0 +1,21 @@
+(function ()
+{
+ var workerSource = document.getElementById('inlineWorker');
+ var blob = new Blob([workerSource.textContent]);
+
+ // can I create a new script tag like this? ack...
+ var url = window.URL.createObjectURL(blob);
+
+ try {
+ var worker = new Worker(url);
+ }
+ catch (e) {
+ done();
+ }
+
+ worker.addEventListener('message', function(e) {
+ assert_unreached("script ran");
+ }, false);
+
+ worker.postMessage('');
+})();
diff --git a/testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js b/testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js
new file mode 100644
index 0000000000..08535fa552
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js
@@ -0,0 +1,3 @@
+// Identical to simpleSourcedScript.js but with a different hash, thanks to
+// this comment!
+window.postMessage(document.currentScript.id, "*");
diff --git a/testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js.headers b/testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js.headers
new file mode 100644
index 0000000000..cb762eff80
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/crossoriginScript.js.headers
@@ -0,0 +1 @@
+Access-Control-Allow-Origin: *
diff --git a/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html
new file mode 100644
index 0000000000..6ee3785dc8
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html
@@ -0,0 +1,19 @@
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Content-Security-Policy-Report-Only: script-src 'unsafe-inline'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}} -->
+</head>
+<body>
+ <script>
+ var t = async_test("Eval is allowed because the CSP is report-only");
+ try {
+ eval("t.done()");
+ } catch {
+ t.step(function() { assert_true(false, "The eval should have execute succesfully"); })
+ }
+ </script>
+
+ <script async defer src="../support/checkReport.sub.js?reportField=blocked-uri&reportValue=eval"></script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html.sub.headers
new file mode 100644
index 0000000000..09d8adec37
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode-and-sends-report.html.sub.headers
@@ -0,0 +1,2 @@
+Set-Cookie: eval-allowed-in-report-only-mode-and-sends-report={{$id:uuid()}}; Path=/content-security-policy/script-src
+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/script-src/eval-allowed-in-report-only-mode.html b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode.html
new file mode 100644
index 0000000000..eebc8f026f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Content-Security-Policy-Report-Only: script-src 'unsafe-inline' -->
+</head>
+<body>
+ <script>
+ var t = async_test("Eval is allowed because the CSP is report-only");
+ try {
+ eval("t.done()");
+ } catch {
+ t.step(function() { assert_true(false, "The eval should have execute succesfully"); })
+ }
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode.html.sub.headers
new file mode 100644
index 0000000000..b9b5d81acc
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/eval-allowed-in-report-only-mode.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy-Report-Only: script-src 'unsafe-inline'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/externalScript.js b/testing/web-platform/tests/content-security-policy/script-src/externalScript.js
new file mode 100644
index 0000000000..2920b03c9b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/externalScript.js
@@ -0,0 +1 @@
+externalRan = true; \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html
new file mode 100644
index 0000000000..0d0f46fda4
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-c6TzhBw/snA+hlDMGOuKLWXIkb2sawA/S1wbSe6FeEM=';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t1 = async_test("Should convert the script contents to UTF-8 before hashing");
+ window.addEventListener("securitypolicyviolation", t1.unreached_func("Should not have fired a spv"));
+ </script>
+
+ <!-- µ (micro sign) has the value of 0xB5 in latin-1 and of 0xC2B5 in utf-8 but the hash value should be the same as the utf-8 computed one -->
+ <script>
+ // µ - latin micro sign
+ t1.done();
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html.sub.headers
new file mode 100644
index 0000000000..acc92f4e80
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-1.html.sub.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=iso-8859-1
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html
new file mode 100644
index 0000000000..d4a0de41e2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-hbNM6T3uO5pu4o5YfNnUmwtq5VHHMr7V5ospXtx9bqU=';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t3 = async_test("Should convert the script contents to UTF-8 before hashing");
+ window.addEventListener("securitypolicyviolation", t3.unreached_func("Should not have fired a spv"));
+ </script>
+
+ <!-- « (latin capital letter g with breve) has the value of 0xAB in latin-3 and of 0xC49E in utf-8 but the hash value should be the same as the utf-8 computed one -->
+ <script>
+ // « - latin capital letter g with breve
+ t3.done();
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html.sub.headers
new file mode 100644
index 0000000000..ae3e03dae1
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-3.html.sub.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=iso-8859-3
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html
new file mode 100644
index 0000000000..62876f1e43
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-ST0rpskqtEC0Q0hqbIAZFeE1KBMJeGZGyYaTcTkieG8=';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t2 = async_test("Should convert the script contents to UTF-8 before hashing");
+ window.addEventListener("securitypolicyviolation", t2.unreached_func("Should not have fired a spv"));
+ </script>
+
+ <!-- ì (greek small letter mu) has the value of 0xEC in latin-7 and of 0xCEBC in utf-8 but the hash value should be the same as the utf-8 computed one -->
+ <script>
+ // ì - greek small letter mu
+ t2.done();
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html.sub.headers
new file mode 100644
index 0000000000..9550b0de30
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-7.html.sub.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=iso-8859-7
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html
new file mode 100644
index 0000000000..8c1db6d203
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-hbNM6T3uO5pu4o5YfNnUmwtq5VHHMr7V5ospXtx9bqU=';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t3 = async_test("Should convert the script contents to UTF-8 before hashing");
+ window.addEventListener("securitypolicyviolation", t3.unreached_func("Should not have fired a spv"));
+ </script>
+
+ <!-- Ð (latin capital letter g with breve) has the value of 0xD0 in latin-9 and of 0xC49E in utf-8 but the hash value should be the same as the utf-8 computed one -->
+ <script>
+ // Ð - latin capital letter g with breve
+ t3.done();
+ </script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html.sub.headers
new file mode 100644
index 0000000000..6382ff86a7
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/iso-8859-9.html.sub.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=iso-8859-9
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html
new file mode 100644
index 0000000000..58730a72cc
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html
@@ -0,0 +1,31 @@
+<html>
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-YJSaNEZFStZqU2Mp2EttwhcP2aT9lnDvexn+BM2HfKo=';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t = async_test("Should convert the script contents to UTF-8 before hashing");
+ var count = 0;
+ var script_ran = function() {
+ // if both blocks run the tests is succsssful
+ if (++count == 2) t.done();
+ }
+ window.addEventListener("securitypolicyviolation", t.unreached_func("Should not have fired a spv"));
+
+ // Insert a script element that contains the U+FFFD replacement character
+ var scr1 = document.createElement('script');
+ scr1.text ="//\uFFFD\nscript_ran();";
+ document.body.appendChild(scr1);
+
+ // Insert a script element that contains a surrogate character but it otherwise
+ // entirely identical to the previously inserted one, the surrogate should be
+ // be converted to U+FFFD when converting to UTF-8 so it should have the
+ // same hash as the one inserted before
+ var scr2 = document.createElement('script');
+ scr2.text ="//\uD801\nscript_ran();";
+ document.body.appendChild(scr2);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html.sub.headers
new file mode 100644
index 0000000000..2d1c08b9e8
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8-lone-surrogate.html.sub.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=utf-8
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html
new file mode 100644
index 0000000000..b770cba246
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html
@@ -0,0 +1,36 @@
+<html>
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc'
+ 'sha256-c6TzhBw/snA+hlDMGOuKLWXIkb2sawA/S1wbSe6FeEM='
+ 'sha256-ST0rpskqtEC0Q0hqbIAZFeE1KBMJeGZGyYaTcTkieG8='
+ 'sha256-hbNM6T3uO5pu4o5YfNnUmwtq5VHHMr7V5ospXtx9bqU=';">
+ <!-- hashes matching the 3 script blocks below -->
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t1 = async_test("Should convert the script contents to UTF-8 before hashing - latin micro sign");
+ window.addEventListener("securitypolicyviolation", t1.unreached_func("Should not have fired a spv"));
+ var t2 = async_test("Should convert the script contents to UTF-8 before hashing - greek small letter mu");
+ window.addEventListener("securitypolicyviolation", t2.unreached_func("Should not have fired a spv"));
+ var t3 = async_test("Should convert the script contents to UTF-8 before hashing - latin capital letter g with breve");
+ window.addEventListener("securitypolicyviolation", t3.unreached_func("Should not have fired a spv"));
+ </script>
+
+ <!-- the hash values of these script blocks should match the same values
+ of identical script blocks in documents with other encodings -->
+ <script>
+ // µ - latin micro sign
+ t1.done();
+ </script>
+ <script>
+ // μ - greek small letter mu
+ t2.done();
+ </script>
+ <script>
+ // Äž - latin capital letter g with breve
+ t3.done();
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html.sub.headers
new file mode 100644
index 0000000000..2d1c08b9e8
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/hash-always-converted-to-utf-8/utf-8.html.sub.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=utf-8
diff --git a/testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-allowed.sub.html b/testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-allowed.sub.html
new file mode 100644
index 0000000000..5a8cdec847
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-allowed.sub.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'self'">
+ <title>injected-inline-script-allowed</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["Pass 1 of 2","Pass 2 of 2"]'></script>
+ <script src='../support/alertAssert.sub.js?alerts=[]'></script>
+</head>
+
+<body>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("Fail");
+ });
+ </script>
+ <script src="support/inject-script.js"></script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-blocked.sub.html b/testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-blocked.sub.html
new file mode 100644
index 0000000000..45b7414890
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/injected-inline-script-blocked.sub.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc'; connect-src 'self';">
+ <title>injected-inline-script-blocked</title>
+ <script nonce='abc' src="/resources/testharness.js"></script>
+ <script nonce='abc' src="/resources/testharnessreport.js"></script>
+ <script nonce='abc' src='../support/logTest.sub.js?logs=["violated-directive=script-src-elem","blocked-uri=inline"]'></script>
+ <script nonce='abc' src='../support/alertAssert.sub.js?alerts=[]'></script>
+</head>
+
+<body>
+ <script nonce='abc'>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("violated-directive=" + e.violatedDirective);
+ log("blocked-uri=" + e.blockedURI);
+ });
+ </script>
+ <script src="support/inject-script.js"></script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/inlineSuccessTest.js b/testing/web-platform/tests/content-security-policy/script-src/inlineSuccessTest.js
new file mode 100644
index 0000000000..1f0d7ae715
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/inlineSuccessTest.js
@@ -0,0 +1,12 @@
+var t_spv = async_test("Should not fire policy violation events");
+window.addEventListener("securitypolicyviolation", t_spv.unreached_func("Should have not fired any securitypolicyviolation event"));
+
+var inlineRan = false;
+
+onload = function() {
+ test(function() {
+ assert_true(inlineRan, 'Unsafe inline script ran.')},
+ 'Inline script in a script tag should run with an unsafe-inline directive'
+ );
+ t_spv.done();
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/inlineTests.js b/testing/web-platform/tests/content-security-policy/script-src/inlineTests.js
new file mode 100644
index 0000000000..3c0712b449
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/inlineTests.js
@@ -0,0 +1,22 @@
+var t1 = async_test("Inline script block");
+var t2 = async_test("Inline event handler");
+
+onload = function() {t1.done(); t2.done();};
+
+var t_spv = async_test("Should fire policy violation events");
+var block_event_fired = false;
+var handler_event_fired = false;
+window.addEventListener("securitypolicyviolation", t_spv.step_func(function(e) {
+ if (e.violatedDirective == "script-src-elem") {
+ assert_false(block_event_fired);
+ block_event_fired = true;
+ } else if (e.violatedDirective == "script-src-attr") {
+ assert_false(handler_event_fired);
+ handler_event_fired = true;
+ } else {
+ assert_unreached("Unexpected directive broken");
+ }
+ if (block_event_fired && handler_event_fired) {
+ t_spv.done();
+ }
+}));
diff --git a/testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.html b/testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.html
new file mode 100644
index 0000000000..ae4d8227ed
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Window.open should not open javascript url if not allowed.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc';">
+ <script nonce='abc' src='/resources/testharness.js'></script>
+ <script nonce='abc' src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce='abc'>
+ var t = async_test("Check that a securitypolicyviolation event is fired");
+ window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
+ assert_equals(e.blockedURI, "inline");
+ assert_equals(e.violatedDirective, "script-src-elem");
+ }));
+
+ window.open('javascript:test(function() { assert_unreached("FAIL")});', 'new');
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.html.sub.headers
new file mode 100644
index 0000000000..b54c91e74e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/javascript-window-open-blocked.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: javascript-window-open-blocked={{$id:uuid()}}; Path=/content-security-policy/script-src/
+Content-Security-Policy: script-src 'nonce-abc'; report-uri /reporting/resources/report.py?op=put&reportID={{$id}}
diff --git a/testing/web-platform/tests/content-security-policy/script-src/nonce-enforce-blocked.html b/testing/web-platform/tests/content-security-policy/script-src/nonce-enforce-blocked.html
new file mode 100644
index 0000000000..25343a5d4d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/nonce-enforce-blocked.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc'">
+<script src="/resources/testharness.js" nonce="abc"></script>
+<script src="/resources/testharnessreport.js" nonce="abc"></script>
+<script nonce="abc">
+ var t = async_test("Unnonced scripts generate reports.");
+ var events = 0;
+ var firstLine = 38;
+ var expectations = {}
+ expectations[firstLine] = true;
+ expectations[firstLine + 3] = true;
+ expectations[firstLine + 6] = true;
+ expectations[firstLine + 9] = true;
+ expectations[firstLine + 12] = true;
+ expectations[firstLine + 15] = true;
+ expectations[firstLine + 18] = true;
+ expectations["/content-security-policy/support/nonce-should-be-blocked.js?1"] = true;
+ expectations["/content-security-policy/support/nonce-should-be-blocked.js?2"] = true;
+ expectations["/content-security-policy/support/nonce-should-be-blocked.js?3"] = true;
+ expectations["/content-security-policy/support/nonce-should-be-blocked.js?4"] = true;
+ expectations["/content-security-policy/support/nonce-should-be-blocked.js?5"] = true;
+
+ document.addEventListener('securitypolicyviolation', t.step_func(e => {
+ if (e.lineNumber) {
+ // Verify that the line is expected, then clear the expectation:
+ assert_true(expectations[e.lineNumber], "Line number: " + e.lineNumber);
+ assert_equals(e.blockedURI, "inline");
+ } else {
+ // Otherwise, verify that the URL is expected, then clear the expectation:
+ var url = new URL(e.blockedURI);
+ assert_true(expectations[url.pathname + url.search], "URL: " + e.blockedURI);
+ }
+ events++;
+ if (events == 12)
+ t.done();
+ }));
+</script>
+<script>
+ t.unreached_func("No nonce, no execution.")();
+</script>
+<script nonce="xyz">
+ t.unreached_func("Bad nonce, no execution.")();
+</script>
+<script <script nonce="abc">
+ t.unreached_func("'<script' attribute, no execution.")();
+</script>
+<script attribute<script nonce="abc">
+ t.unreached_func("'attribute<script', no execution.")();
+</script>
+<script attribute=<script nonce="abc">
+ t.unreached_func("'<script' value, no execution.")();
+</script>
+<script attribute=value<script nonce="abc">
+ t.unreached_func("'value<script', no execution.")();
+</script>
+<script attribute="" attribute=<style nonce="abc">
+ t.unreached_func("Duplicate attribute, no execution.")();
+</script>
+<script src="../support/nonce-should-be-blocked.js?1" <script nonce="abc"></script>
+<script src="../support/nonce-should-be-blocked.js?2" attribute=<script nonce="abc"></script>
+<script src="../support/nonce-should-be-blocked.js?3" <style nonce="abc"></script>
+<script src="../support/nonce-should-be-blocked.js?4" attribute=<style nonce="abc"></script>
+<script src="../support/nonce-should-be-blocked.js?5" attribute=<style nonce="abc"></script>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_1.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_1.html
new file mode 100644
index 0000000000..d66253c6a1
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Inline script should not run without 'unsafe-inline' script-src directive.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ <script src='inlineTests.js'></script>
+</head>
+<body>
+ <h1>Inline script should not run without 'unsafe-inline' script-src directive, even for script-src 'self'.</h1>
+ <div id='log'></div>
+
+ <script>
+ t1.step(function() {assert_unreached('Unsafe inline script ran.');});
+ </script>
+
+ <img src='doesnotexist.jpg' onerror='t2.step(function() { assert_unreached("Unsafe inline event handler ran.") });'>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_10.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_10.html
new file mode 100644
index 0000000000..7c1c9f29b6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_10.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>data: as script src should not run with a policy that doesn't specify data: as an allowed source</title>
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <h1>data: as script src should not run with a policy that doesn't specify data: as an allowed source</h1>
+ <div id='log'></div>
+
+ <script>
+ var dataScriptRan = false;
+ var t_spv = async_test("Test that securitypolicyviolation event is fired");
+
+ window.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src-elem");
+ }));
+ </script>
+
+ <!-- This is our test case, but we don't expect it to actually execute if CSP is working. -->
+ <script src="data:text/javascript;charset=utf-8;base64,ZGF0YVNjcmlwdFJhbiA9IHRydWU7"></script>
+
+ <script>
+ test(function () {
+ assert_false(dataScriptRan, "data script ran");
+ }, "Verify that data: as script src doesn't run with this policy");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_10_1.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_10_1.html
new file mode 100644
index 0000000000..a1e2f72cdb
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_10_1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>data: as script src should run with a policy that specifies data: as an allowed source but not 'unsafe-inline'</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' data:;">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <h1>data: as script src should run with a policy that specifies data: as an allowed source but not 'unsafe-inline'</h1>
+ <div id='log'></div>
+
+ <script src="10_1_support_1.js"></script>
+
+ <script src="data:text/javascript;charset=utf-8;base64,ZGF0YVNjcmlwdFJhbiA9IHRydWU7"></script>
+
+ <script src="10_1_support_2.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_2.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_2.html
new file mode 100644
index 0000000000..a68945cb85
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_2.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Inline script should not run without 'unsafe-inline' script-src directive.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src *;">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ <script src='inlineTests.js'></script>
+</head>
+<body>
+ <h1>Inline script should not run without 'unsafe-inline' script-src directive, even for script-src *.</h1>
+ <div id='log'></div>
+
+ <script>
+ t1.step(function() {assert_unreached('Unsafe inline script ran.');});
+ </script>
+
+ <img src='doesnotexist.jpg' onerror='t2.step(function() { assert_unreached("Unsafe inline event handler ran.") });'>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_2_1.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_2_1.html
new file mode 100644
index 0000000000..2641c867f6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_2_1.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Inline script attached by DOM manipulation should not run without an 'unsafe-inline' script-src policy, even with default-src *</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src *;">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <h1>Inline script attached by DOM manipulation should not run without an 'unsafe-inline' script-src policy, even with default-src *</h1>
+ <div id="log"></div>
+
+ <div id=attachHere></div>
+
+ <script id=emptyScript></script>
+
+ <div id=emptyDiv></div>
+
+ <script src="addInlineTestsWithDOMManipulation.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_3.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_3.html
new file mode 100644
index 0000000000..bf7a6921b4
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_3.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Positive test case: Inline script should run 'unsafe-inline' script-src directive.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ <script src='inlineSuccessTest.js'></script>
+</head>
+<body>
+ <h1>Positive test case: Inline script should run 'unsafe-inline' script-src directive.</h1>
+ <div id='log'></div>
+
+ <script>
+ inlineRan = true;
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4.html
new file mode 100644
index 0000000000..d4e2067f96
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>eval() should not run without 'unsafe-eval' script-src directive.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <h1>eval() should not run without 'unsafe-eval' script-src directive.</h1>
+ <div id='log'></div>
+
+ <script>
+ var t_spv = async_test("Test that securitypolicyviolation event is fired");
+
+ window.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src");
+ }));
+
+ var evalRan = false;
+
+ test(function() {assert_throws_js(EvalError, function() { eval('evalRan = true;') })}, "eval() should throw without 'unsafe-eval' keyword source in script-src directive.");
+
+ test(function() {assert_false(evalRan);})
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_1.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_1.html
new file mode 100644
index 0000000000..0eed7a979a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>setTimeout() and setInterval() should not run without 'unsafe-eval' script-src directive.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <h1>setTimeout() and setInterval() should not run without 'unsafe-eval' script-src directive.</h1>
+ <div id='log'></div>
+
+ <script>
+ var t1 = async_test("window.setTimeout()");
+ var t2 = async_test("window.setInterval()");
+ var t_spv = async_test("Test that securitypolicyviolation event is fired");
+ var test_count = 2;
+
+ window.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src");
+ if (--test_count <= 0) {
+ t_spv.done();
+ }
+ }));
+
+
+ onload = function() {t1.done(); t2.done()}
+
+ window.setTimeout('t1.step(function() {assert_unreached("window.setTimeout() ran without unsafe-eval.")})',0);
+ window.setInterval('t2.step(function() {assert_unreached("window.setInterval() ran without unsafe-eval.")})',0);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_2.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_2.html
new file mode 100644
index 0000000000..217125df58
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-1_4_2.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Function() called as a constructor should throw without 'unsafe-eval' script-src directive.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';">
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <h1>Function() called as a constructor should throw without 'unsafe-eval' script-src directive.</h1>
+ <div id='log'></div>
+
+ <script>
+ var t_spv = async_test("Test that securitypolicyviolation event is fired");
+
+ window.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src");
+ }));
+
+
+ test(function() {
+ assert_throws_js(
+ EvalError,
+ function() {
+ var funq = new Function('');
+ funq();
+ })}, "Unsafe eval ran in Function() constructor.");
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html
new file mode 100644
index 0000000000..70b3145727
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Multiple policies with different hashing algorithms still work.</title>
+ <!-- nonces are here just to let all of our scripts run -->
+ <script nonce="abc" src='/resources/testharness.js'></script>
+ <script nonce="abc" src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t = async_test("Test that script executes if allowed by proper hash values");
+ document.addEventListener("securitypolicyviolation", t.unreached_func("Should not have triggered a security event"));
+ var executed = false;
+ </script>
+
+ <!-- test will fail if this script is not allowed to run -->
+ <script>executed = true;</script>
+
+ <script nonce="abc">
+ t.step(function() {
+ assert_true(executed);
+ t.done();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers
new file mode 100644
index 0000000000..89f99e621f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.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
+Content-Security-Policy: script-src 'sha256-EpVP4fTImWaRzBRBw/wrdfLhGTe/1U+CaBP1LNeKUIE=' 'nonce-abc';
+Content-Security-Policy: script-src 'sha384-skw7BVxHbmE2umPGMd1kX+ye6qBeHAb875erPoD8ilKv1LkjKR+WFi7N85ORMdhS' 'nonce-abc'; \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html
new file mode 100644
index 0000000000..da9e60f874
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Multiple policies some using hashes some not using hashes still work.</title>
+ <!-- nonces are here just to let all of our scripts run -->
+ <script nonce="abc" src='/resources/testharness.js'></script>
+ <script nonce="abc" src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t = async_test("Test that script executes if allowed by proper hash values");
+ document.addEventListener("securitypolicyviolation", t.unreached_func("Should not have triggered a security event"));
+ var executed = false;
+ </script>
+
+ <!-- test will fail if this script is not allowed to run -->
+ <script>executed = true;</script>
+
+ <script nonce="abc">
+ t.step(function() {
+ assert_true(executed);
+ t.done();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.html.sub.headers
new file mode 100644
index 0000000000..83fe7f7005
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-multiple-policies-one-using-hashing-algorithms.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
+Content-Security-Policy: script-src 'sha256-EpVP4fTImWaRzBRBw/wrdfLhGTe/1U+CaBP1LNeKUIE=' 'nonce-abc';
+Content-Security-Policy: script-src 'self' 'unsafe-inline'; \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-overrides-default-src.sub.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-overrides-default-src.sub.html
new file mode 100644
index 0000000000..5a0dfe50e1
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-overrides-default-src.sub.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="default-src about:; script-src 'self' 'unsafe-inline'; style-src 'self'; connect-src 'self';">
+ <title>script-src-overrides-default-src</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["PASS 1 of 2","PASS 2 of 2"]'></script>
+ <script src='../support/alertAssert.sub.js?alerts=[]'></script>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log("Fail");
+ });
+ </script>
+</head>
+
+<body onload="log(&apos;PASS 2 of 2&apos;)">
+ <script>
+ log('PASS 1 of 2');
+
+ </script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html
new file mode 100644
index 0000000000..3c4e39e825
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>A report-only policy that does not allow a script should not affect an enforcing policy using hashes.</title>
+ <!-- nonces are here just to let all of our scripts run -->
+ <script nonce="abc" src='/resources/testharness.js'></script>
+ <script nonce="abc" src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t_spv = async_test("Should fire securitypolicyviolation event");
+ window.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src-elem");
+ assert_equals(e.disposition, "report");
+ }));
+ var externalRan = false;
+ </script>
+ <script src='./externalScript.js'
+ integrity="sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0="></script>
+ <script nonce="abc">
+ test(function() {
+ assert_true(externalRan, 'External script ran.');
+ }, 'External script in a script tag with matching SRI hash should run.');
+ </script></body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.html.sub.headers
new file mode 100644
index 0000000000..7f03464d4d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy.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
+Content-Security-Policy: script-src 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'nonce-abc'
+Content-Security-Policy-Report-Only: script-src 'nonce-abc'; \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html
new file mode 100644
index 0000000000..850f4b2c2e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>A report-only policy that does not allow a script should not affect an enforcing policy using hashes.</title>
+ <!-- nonces are here just to let all of our scripts run -->
+ <script nonce="abc" src='/resources/testharness.js'></script>
+ <script nonce="abc" src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+ <script nonce="abc">
+ var t = async_test("Test that script executes if allowed by proper hash values");
+ var t_spv = async_test("Test that the securitypolicyviolation event is fired");
+ document.addEventListener("securitypolicyviolation", t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src-elem");
+ assert_equals(e.disposition, "report");
+ assert_equals(e.blockedURI, "inline");
+ }));
+ var executed = false;
+ </script>
+
+ <!-- test will fail if this script is not allowed to run -->
+ <script>executed = true;</script>
+
+ <script nonce="abc">
+ t.step(function() {
+ assert_true(executed);
+ t.done();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.html.sub.headers
new file mode 100644
index 0000000000..1237c247a6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-report-only-policy-works-with-hash-policy.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
+Content-Security-Policy: script-src 'sha256-EpVP4fTImWaRzBRBw/wrdfLhGTe/1U+CaBP1LNeKUIE=' 'nonce-abc'
+Content-Security-Policy-Report-Only: script-src 'nonce-abc'; \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.sub.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.sub.html
new file mode 100644
index 0000000000..b59206824d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.sub.html
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>External scripts with matching SRI hash should be allowed.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=' -->
+</head>
+
+<body>
+ <h1>External scripts with matching SRI hash should be allowed.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ var port = "{{ports[http][0]}}";
+ if (location.protocol === "https:")
+ port = "{{ports[https][0]}}";
+ var crossorigin_base = location.protocol + "//{{domains[www]}}:" + port;
+
+ // Test name, src, integrity, expected to run.
+ var test_cases = [
+ [ 'matching integrity',
+ './simpleSourcedScript.js',
+ 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=',
+ true ],
+ [ 'multiple matching integrity',
+ './simpleSourcedScript.js',
+ 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=',
+ true ],
+ [ 'no integrity',
+ './simpleSourcedScript.js',
+ '',
+ false ],
+ [ 'matching plus unsupported integrity',
+ './simpleSourcedScript.js',
+ 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha999-xyz',
+ true ],
+ [ 'mismatched integrity',
+ './simpleSourcedScript.js',
+ 'sha256-xyz',
+ false ],
+ [ 'multiple mismatched integrity',
+ './simpleSourcedScript.js',
+ 'sha256-xyz sha256-zyx',
+ false ],
+ [ 'partially matching integrity',
+ './simpleSourcedScript.js',
+ 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha256-xyz',
+ false ],
+ [ 'crossorigin no integrity but allowed host',
+ crossorigin_base + '/content-security-policy/script-src/crossoriginScript.js',
+ '',
+ true ],
+ [ 'crossorigin mismatched integrity but allowed host',
+ crossorigin_base + '/content-security-policy/script-src/crossoriginScript.js',
+ 'sha256-kKJ5c48yxzaaSBupJSCmY50hkD8xbVgZgLHLtmnkeAo=',
+ true ],
+ ];
+
+ test(_ => {
+ for (item of test_cases) {
+ async_test(t => {
+ var s = document.createElement('script');
+ s.id = item[0].replace(' ', '-');
+ s.src = item[1];
+ s.integrity = item[2];
+ s.setAttribute('crossorigin', 'anonymous');
+
+ if (item[3]) {
+ s.onerror = t.unreached_func("Script should load! " + s.src);
+ window.addEventListener('message', t.step_func(e => {
+ if (e.data == s.id)
+ t.done();
+ }));
+ } else {
+ s.onerror = t.step_func_done();
+ window.addEventListener('message', t.step_func(e => {
+ if (e.data == s.id)
+ assert_unreached("Script should not execute!");
+ }));
+ }
+
+ document.body.appendChild(s);
+ }, item[0]);
+ }
+ }, "Load all the tests.");
+ </script>
+
+ <script nonce='dummy'>
+ var externalRan = false;
+ </script>
+ <script src='./externalScript.js'
+ integrity="sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0="></script>
+ <script nonce='dummy'>
+ test(function() {
+ assert_true(externalRan, 'External script ran.');
+ }, 'External script in a script tag with matching SRI hash should run.');
+ </script>
+
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.sub.html.sub.headers
new file mode 100644
index 0000000000..25cd6541ac
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-sri_hash.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 {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA='
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html
new file mode 100644
index 0000000000..96ef2496b5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Scripts injected via `eval` are allowed with `strict-dynamic` with `unsafe-eval`.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' 'unsafe-eval' -->
+</head>
+
+<body>
+ <h1>Scripts injected via `eval` are allowed with `strict-dynamic` with `unsafe-eval`.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ var evalScriptRan = false;
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.unreached_func('No CSP violation report has fired.'));
+ try {
+ eval("evalScriptRan = true;");
+ } catch (e) {
+ assert_unreached("`eval` should be allowed with `strict-dynamic` with `unsafe-eval`.");
+ }
+ assert_true(evalScriptRan);
+ t.done();
+ }, "Script injected via `eval` is allowed with `strict-dynamic` with `unsafe-eval`.");
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html.headers
new file mode 100644
index 0000000000..dc5f30a03a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_eval.html.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 'strict-dynamic' 'nonce-dummy' 'unsafe-eval'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html
new file mode 100644
index 0000000000..3041db056f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Scripts injected via `new Function()` are allowed with `strict-dynamic` with `unsafe-eval`.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' 'unsafe-eval' -->
+</head>
+
+<body>
+ <h1>Scripts injected via `new Function()` are allowed with `strict-dynamic` with `unsafe-eval`.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ var newFunctionScriptRan = false;
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.unreached_func('No CSP violation report has fired.'));
+ try {
+ new Function('newFunctionScriptRan = true;')();
+ } catch (e) {
+ assert_unreached("`new Function()` should be allowed with `strict-dynamic` with `unsafe-eval`.");
+ }
+ assert_true(newFunctionScriptRan);
+ t.done();
+ }, "Script injected via `new Function()` is allowed with `strict-dynamic` with `unsafe-eval`.");
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html.headers
new file mode 100644
index 0000000000..dc5f30a03a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_and_unsafe_eval_new_function.html.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 'strict-dynamic' 'nonce-dummy' 'unsafe-eval'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html
new file mode 100644
index 0000000000..4edef30109
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Source expressions are discarded with `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'self' 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Source expressions are discarded with `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'allowedScript') {
+ assert_unreached('Allowed scripts without a correct nonce are not permitted with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
+ assert_equals(e.effectiveDirective, 'script-src-elem');
+ }));
+ }, 'Allowed scripts without a correct nonce are not permitted with `strict-dynamic`.');
+ </script>
+ <script id='allowedScript' src='simpleSourcedScript.js'></script>
+
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html.headers
new file mode 100644
index 0000000000..8499eb0559
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_discard_source_expressions.html.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 'self' 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html
new file mode 100644
index 0000000000..91d12ed7bd
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>A separate policy with more nonces works correctly with `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served:
+ 1) Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy'
+ 2) Content-Security-Policy: script-src 'nonce-dummy' 'nonce-dummy2'
+ -->
+</head>
+
+<body>
+ <h1>A separate policy with more nonces works correctly with `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'unNonced-appendChild') {
+ assert_unreached('Unnonced script injected via `appendChild` is not allowed with `strict-dynamic` + a nonce-only double policy.');
+ }
+ }));
+
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'unNonced-appendChild') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ var e = document.createElement('script');
+ e.id = 'unNonced-appendChild';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.onload = t.unreached_func('OnLoad should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Unnonced script injected via `appendChild` is not allowed with `strict-dynamic` + a nonce-only double policy.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'nonced-appendChild') {
+ t.done();
+ }
+ }));
+
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'nonced-appendChild') {
+ return;
+ }
+ assert_unreached('No CSP violation report has fired.');
+ }));
+
+ var e = document.createElement('script');
+ e.setAttribute('nonce', 'dummy2');
+ e.id = 'nonced-appendChild';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` with a correct nonce is allowed with `strict-dynamic` + a nonce-only double policy.');
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html.headers
new file mode 100644
index 0000000000..63d96aaf1e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_different_nonce.html.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
+Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy'
+Content-Security-Policy: script-src 'nonce-dummy' 'nonce-dummy2'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html
new file mode 100644
index 0000000000..39126de58f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Source expressions in a separate policy are honored with `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served:
+ 1) Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy'
+ 2) Content-Security-Policy: script-src 'self' 'nonce-dummy'
+ -->
+</head>
+
+<body>
+ <h1>Source expressions in a separate policy are honored with `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'allowed-appendChild') {
+ t.done();
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'allowed-appendChild') {
+ return;
+ }
+ assert_unreached('Script injected via `appendChild` is permitted with `strict-dynamic` + a nonce+allowed double policy.');
+ }));
+
+ var e = document.createElement('script');
+ e.id = 'allowed-appendChild';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` is permitted with `strict-dynamic` + a nonce+allowed double policy.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'nonAllowed-appendChild') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ assert_equals(violation.originalPolicy, "script-src 'self' 'nonce-dummy'");
+ t.done();
+ }));
+
+ var e = document.createElement('script');
+ e.id = 'nonAllowed-appendChild';
+ e.src = '{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/nonexisting.js?' + e.id;
+ e.onload = t.unreached_func('OnLoad should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Non-allowed script injected via `appendChild` is not permitted with `strict-dynamic` + a nonce+allowed double policy.');
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html.headers
new file mode 100644
index 0000000000..5b4078efd3
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_honor_source_expressions.sub.html.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
+Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy'
+Content-Security-Policy: script-src 'self' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html
new file mode 100644
index 0000000000..1ceb74c63d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>A separate Report-Only policy does not influence `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served:
+ 1) Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy'
+ 2) Content-Security-Policy-Report-Only: script-src 'none'
+ -->
+</head>
+
+<body>
+ <h1>A separate Report-Only policy does not influence `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'appendChild-reportOnly') {
+ t.done();
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'appendChild-reportOnly') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ // Check that the violation comes from the Report-Only policy.
+ assert_equals(violation.originalPolicy, "script-src 'none'");
+ t.done();
+ }));
+ var e = document.createElement('script');
+ e.id = 'appendChild-reportOnly';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` is allowed with `strict-dynamic` + Report-Only `script-src \'none\'` policy.');
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html.headers
new file mode 100644
index 0000000000..7883f80ef6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_double_policy_report_only.html.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
+Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy'
+Content-Security-Policy-Report-Only: script-src 'none'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html
new file mode 100644
index 0000000000..3a6056f566
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Scripts injected via `eval` are not allowed with `strict-dynamic` without `unsafe-eval`.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Scripts injected via `eval` are not allowed with `strict-dynamic` without `unsafe-eval`.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ var evalScriptRan = false;
+
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
+ assert_false(evalScriptRan);
+ assert_equals(e.effectiveDirective, 'script-src');
+ assert_equals(e.blockedURI, 'eval');
+ }));
+
+ assert_throws_js(Error,
+ function() {
+ try {
+ eval("evalScriptRan = true;");
+ } catch (e) {
+ throw new Error();
+ }
+ });
+ }, "Script injected via `eval` is not allowed with `strict-dynamic` without `unsafe-eval`.");
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html.headers
new file mode 100644
index 0000000000..b7918c9332
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_eval.html.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 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html
new file mode 100644
index 0000000000..e4ce1e5944
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>`strict-dynamic` allows scripts matching hashes present in the policy.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' 'sha256-yU6Q7nD1TCBB9JvY06iIJ8ONLOPU4g8ml5JCDgXkv+M=' 'sha256-EEoi70frWHkGFhK51NVIJkXpq72aPxSCNZEow37ZmRA=' -->
+</head>
+
+<body>
+ <h1>`strict-dynamic` allows scripts matching hashes present in the policy.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ var hashScriptRan = false;
+ window.addEventListener('securitypolicyviolation', function(e) {
+ assert_unreached('CSP violation reports should not fire.');
+ });
+ </script>
+
+ <!-- Hash: 'sha256-EEoi70frWHkGFhK51NVIJkXpq72aPxSCNZEow37ZmRA=' -->
+ <script>
+ hashScriptRan = true;
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ assert_true(hashScriptRan);
+ t.done();
+ }, "Script matching SHA256 hash is allowed with `strict-dynamic`.");
+ </script>
+
+ <!-- Hash: 'sha256-IFt1v6itHgqlrtInbPm/y7qyWcAlDbPgZM+92C5EZ5o=' -->
+ <script>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'hashScript') {
+ t.done();
+ }
+ }));
+ var e = document.createElement('script');
+ e.id = 'hashScript';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` from a script matching SHA256 hash is allowed with `strict-dynamic`.');
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html.headers
new file mode 100644
index 0000000000..0d824d8b0e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_hashes.html.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 'strict-dynamic' 'nonce-dummy' 'sha256-yU6Q7nD1TCBB9JvY06iIJ8ONLOPU4g8ml5JCDgXkv+M=' 'sha256-EEoi70frWHkGFhK51NVIJkXpq72aPxSCNZEow37ZmRA='
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html
new file mode 100644
index 0000000000..29a2a59573
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>`strict-dynamic` does not drop allowed source expressions in `img-src`.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: img-src 'strict-dynamic' 'self' -->
+</head>
+
+<body>
+ <h1>`strict-dynamic` does not drop allowed source expressions in `img-src`.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ assert_unreached('No CSP violation report has fired.');
+ });
+
+ async_test(function(t) {
+ var e = document.createElement('img');
+ e.id = 'allowedImage';
+ e.src = '/content-security-policy/support/pass.png';
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ e.onload = t.step_func_done();
+ document.body.appendChild(e);
+ }, '`strict-dynamic` does not drop allowed source expressions in `img-src`.');
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html.headers
new file mode 100644
index 0000000000..75a41c9e25
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_in_img-src.html.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: img-src 'strict-dynamic' 'self'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html
new file mode 100644
index 0000000000..f7625afdaf
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Script injected via `javascript:` URIs are not allowed with `strict-dynamic`.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Script injected via `javascript:` URIs are not allowed with `strict-dynamic`.</h1>
+ <div id='log'></div>
+ <a id='javascriptUri' href='javascript:javascriptUriScriptRan = true;'></a>
+
+ <script nonce='dummy'>
+ var javascriptUriScriptRan = false;
+
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
+ assert_false(javascriptUriScriptRan);
+ assert_equals(e.effectiveDirective, 'script-src-elem');
+ }));
+
+ document.getElementById('javascriptUri').click();
+ assert_false(javascriptUriScriptRan);
+ }, "Script injected via `javascript:` URIs are not allowed with `strict-dynamic`.");
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.headers
new file mode 100644
index 0000000000..b7918c9332
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.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 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html
new file mode 100644
index 0000000000..fa38b65a23
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>A `strict-dynamic` policy can be served in a META tag.</title>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'strict-dynamic' 'nonce-dummy'">
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>A `strict-dynamic` policy can be served in a META tag.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ assert_unreached('No CSP violation report has fired.');
+ });
+
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'appendChild') {
+ t.done();
+ }
+ }));
+ var e = document.createElement('script');
+ e.id = 'appendChild';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'appendChild-incorrectNonce') {
+ t.done();
+ }
+ }));
+ var e = document.createElement('script');
+ e.id = 'appendChild-incorrectNonce';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.setAttribute('nonce', 'wrong');
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` is allowed with `strict-dynamic`, even if it carries an incorrect nonce.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.appendChildViaTextContent = t.step_func_done();
+ var e = document.createElement('script');
+ e.id = 'appendChild-textContent';
+ e.textContent = "appendChildViaTextContent();";
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` populated via `textContent` is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.appendChildViaTextContentIncorrectNonce = t.step_func_done();
+ var e = document.createElement('script');
+ e.id = 'appendChild-textContent-incorrectNonce';
+ e.setAttribute('nonce', 'wrong');
+ e.textContent = "appendChildViaTextContentIncorrectNonce();";
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` populated via `textContent` is allowed with `strict-dynamic`, even if it carries an incorrect nonce.');
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html.headers
new file mode 100644
index 0000000000..519dcaacb1
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_meta_tag.html.headers
@@ -0,0 +1,4 @@
+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
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html
new file mode 100644
index 0000000000..263d5d1d87
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Scripts injected via `new Function()` are not allowed with `strict-dynamic` without `unsafe-eval`.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Scripts injected via `new Function()` are not allowed with `strict-dynamic` without `unsafe-eval`.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ var newFunctionScriptRan = false;
+
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
+ assert_false(newFunctionScriptRan);
+ assert_equals(e.effectiveDirective, 'script-src');
+ }));
+
+ assert_throws_js(Error,
+ function() {
+ try {
+ new Function('newFunctionScriptRan = true;')();
+ } catch (e) {
+ throw new Error();
+ }
+ });
+ }, "Script injected via 'eval' is not allowed with 'strict-dynamic' without 'unsafe-eval'.");
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html.headers
new file mode 100644
index 0000000000..b7918c9332
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_new_function.html.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 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html
new file mode 100644
index 0000000000..63b7a61247
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Nonced and non parser-inserted scripts should run with `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Nonced and non parser-inserted scripts should run with `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ assert_unreached('No CSP violation report has fired.');
+ });
+
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'appendChild') {
+ t.done();
+ }
+ }));
+ var e = document.createElement('script');
+ e.id = 'appendChild';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'appendChild-incorrectNonce') {
+ t.done();
+ }
+ }));
+ var e = document.createElement('script');
+ e.id = 'appendChild-incorrectNonce';
+ e.src = 'simpleSourcedScript.js?' + e.id;
+ e.setAttribute('nonce', 'wrong');
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` is allowed with `strict-dynamic`, even if it carries an incorrect nonce.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.appendChildViaTextContent = t.step_func_done();
+ var e = document.createElement('script');
+ e.id = 'appendChild-textContent';
+ e.textContent = "appendChildViaTextContent();";
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` populated via `textContent` is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.appendChildViaTextContentIncorrectNonce = t.step_func_done();
+ var e = document.createElement('script');
+ e.id = 'appendChild-textContent-incorrectNonce';
+ e.setAttribute('nonce', 'wrong');
+ e.textContent = "appendChildViaTextContentIncorrectNonce();";
+ e.onerror = t.unreached_func('Error should not be triggered.');
+ document.body.appendChild(e);
+ }, 'Script injected via `appendChild` populated via `textContent` is allowed with `strict-dynamic`, even if it carries an incorrect nonce.');
+ </script>
+
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html.headers
new file mode 100644
index 0000000000..b7918c9332
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted.html.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 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html
new file mode 100644
index 0000000000..ac180d23f5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Scripts without a correct nonce should not run with `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Scripts without a correct nonce should not run with `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
+ assert_equals(e.effectiveDirective, 'script-src-elem');
+ }));
+ }, 'All the expected CSP violation reports have been fired.');
+ </script>
+
+ <script nonce='wrong'>
+ assert_unreached('Inline script with an incorrect nonce should not be executed.');
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html.headers
new file mode 100644
index 0000000000..b7918c9332
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_non_parser_inserted_incorrect_nonce.html.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 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html
new file mode 100644
index 0000000000..c5e33dc425
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html
@@ -0,0 +1,205 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Parser-inserted scripts without a correct nonce are not allowed with `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Parser-inserted scripts without a correct nonce are not allowed with `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite') {
+ assert_unreached('Parser-inserted script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWrite') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.write('<scr' + 'ipt id="documentWrite" src="simpleSourcedScript.js?documentWrite"></scr' + 'ipt>');
+ }, 'Parser-inserted script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln') {
+ assert_unreached('Parser-inserted script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWriteln') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.writeln('<scr' + 'ipt id="documentWriteln" src="simpleSourcedScript.js?documentWriteln"></scr' + 'ipt>');
+ }, 'Parser-inserted script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite-deferred') {
+ assert_unreached('Parser-inserted deferred script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWrite-deferred') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.write('<scr' + 'ipt defer id="documentWrite-deferred" src="simpleSourcedScript.js?documentWrite-deferred"></scr' + 'ipt>');
+ }, 'Parser-inserted deferred script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln-deferred') {
+ assert_unreached('Parser-inserted deferred script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWriteln-deferred') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.writeln('<scr' + 'ipt defer id="documentWriteln-deferred" src="simpleSourcedScript.js?documentWriteln-deferred"></scr' + 'ipt>');
+ }, 'Parser-inserted deferred script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite-async') {
+ assert_unreached('Parser-inserted async script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWrite-async') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.write('<scr' + 'ipt async id="documentWrite-async" src="simpleSourcedScript.js?documentWrite-async"></scr' + 'ipt>');
+ }, 'Parser-inserted async script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln-async') {
+ assert_unreached('Parser-inserted async script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWriteln-async') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.writeln('<scr' + 'ipt async id="documentWriteln-async" src="simpleSourcedScript.js?documentWriteln-async"></scr' + 'ipt>');
+ }, 'Parser-inserted async script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite-deferred-async') {
+ assert_unreached('Parser-inserted deferred async script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWrite-deferred-async') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.write('<scr' + 'ipt defer async id="documentWrite-deferred-async" src="simpleSourcedScript.js?documentWrite-deferred-async"></scr' + 'ipt>');
+ }, 'Parser-inserted deferred async script via `document.write` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln-deferred-async') {
+ assert_unreached('Parser-inserted deferred async script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ }
+ }));
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.blockedURI.split('?')[1] !== 'documentWriteln-deferred-async') {
+ return;
+ }
+ assert_equals(violation.effectiveDirective, 'script-src-elem');
+ t.done();
+ }));
+
+ document.writeln('<scr' + 'ipt defer async id="documentWriteln-deferred-async " src="simpleSourcedScript.js?documentWriteln-deferred-async "></scr' + 'ipt>');
+ }, 'Parser-inserted deferred async script via `document.writeln` without a correct nonce is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ var innerHTMLScriptRan = false;
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.target.id !== 'innerHTML') {
+ return;
+ }
+ assert_false(innerHTMLScriptRan);
+ assert_equals(violation.effectiveDirective, 'script-src-attr');
+ t.done();
+ }));
+
+ var e = document.createElement('div');
+ e.innerHTML = "<img id='innerHTML' src='/nonexisting.jpg' onerror='innerHTMLScriptRan = true;' style='display:none'>";
+ document.body.appendChild(e);
+ }, 'Script injected via `innerHTML` is not allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ var insertAdjacentHTMLScriptRan = false;
+ async_test(function(t) {
+ window.addEventListener('securitypolicyviolation', t.step_func(function(violation) {
+ if (violation.target.id !== 'insertAdjacentHTML') {
+ return;
+ }
+ assert_false(insertAdjacentHTMLScriptRan);
+ assert_equals(violation.effectiveDirective, 'script-src-attr');
+ t.done();
+ }));
+
+ var e = document.createElement('div');
+ e.insertAdjacentHTML('afterbegin', "<img id='insertAdjacentHTML' src='/nonexisting.jpg' onerror='insertAdjacentHTMLScriptRan = true;' style='display:none'>");
+ document.body.appendChild(e);
+ }, 'Script injected via `insertAdjacentHTML` is not allowed with `strict-dynamic`.');
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers
new file mode 100644
index 0000000000..b7918c9332
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.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 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html
new file mode 100644
index 0000000000..9368089781
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html
@@ -0,0 +1,110 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <title>Parser-inserted scripts with a correct nonce are allowed with `strict-dynamic` in the script-src directive.</title>
+ <script src='/resources/testharness.js' nonce='dummy'></script>
+ <script src='/resources/testharnessreport.js' nonce='dummy'></script>
+
+ <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+</head>
+
+<body>
+ <h1>Parser-inserted scripts with a correct nonce are allowed with `strict-dynamic` in the script-src directive.</h1>
+ <div id='log'></div>
+
+ <script nonce='dummy'>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ assert_unreached('No CSP violation report has fired.');
+ });
+
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite') {
+ t.done();
+ }
+ }));
+ document.write('<scr' + 'ipt nonce="dummy" id="documentWrite" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted script via `document.write` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln') {
+ t.done();
+ }
+ }));
+ document.writeln('<scr' + 'ipt nonce="dummy" id="documentWriteln" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted script via `document.writeln` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite-defer') {
+ t.done();
+ }
+ }));
+ document.write('<scr' + 'ipt defer nonce="dummy" id="documentWrite-defer" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted deferred script via `document.write` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln-defer') {
+ t.done();
+ }
+ }));
+ document.writeln('<scr' + 'ipt defer nonce="dummy" id="documentWriteln-defer" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted deferred script via `document.writeln` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite-async') {
+ t.done();
+ }
+ }));
+ document.write('<scr' + 'ipt async nonce="dummy" id="documentWrite-async" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted async script via `document.write` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln-async') {
+ t.done();
+ }
+ }));
+ document.writeln('<scr' + 'ipt async nonce="dummy" id="documentWriteln-async" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted async script via `document.writeln` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWrite-defer-async') {
+ t.done();
+ }
+ }));
+ document.write('<scr' + 'ipt defer async nonce="dummy" id="documentWrite-defer-async" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted deferred async script via `document.write` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+ <script nonce='dummy'>
+ async_test(function(t) {
+ window.addEventListener('message', t.step_func(function(e) {
+ if (e.data === 'documentWriteln-defer-async') {
+ t.done();
+ }
+ }));
+ document.writeln('<scr' + 'ipt defer async nonce="dummy" id="documentWriteln-defer-async" src="simpleSourcedScript.js"></scr' + 'ipt>');
+ }, 'Parser-inserted deferred async script via `document.writeln` with a correct nonce is allowed with `strict-dynamic`.');
+ </script>
+
+</body>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html.headers b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html.headers
new file mode 100644
index 0000000000..b7918c9332
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted_correct_nonce.html.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 'strict-dynamic' 'nonce-dummy'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker-importScripts.https.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker-importScripts.https.html
new file mode 100644
index 0000000000..681e19547a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker-importScripts.https.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../support/testharness-helper.js'></script>
+
+<meta http-equiv="content-security-policy" content="script-src 'nonce-abc' 'strict-dynamic'">
+
+<script nonce="abc">
+ async_test(t => {
+ assert_no_csp_event_for_url(t, "../support/import-scripts.js");
+ var w = new Worker("../support/import-scripts.js");
+ assert_no_event(t, w, "error");
+ waitUntilEvent(w, "message")
+ .then(t.step_func_done(e => {
+ assert_true(e.data.executed);
+ }));
+ }, "`importScripts(...)` is allowed by 'strict-dynamic'");
+</script>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker.https.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker.https.html
new file mode 100644
index 0000000000..213eb6276d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-strict_dynamic_worker.https.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../support/testharness-helper.js'></script>
+
+<meta http-equiv="content-security-policy" content="script-src 'nonce-abc' 'strict-dynamic'">
+
+<script nonce="abc">
+ assert_worker_is_loaded(
+ "../support/ping.js",
+ "Dedicated worker is allowed via 'strict-dynamic'");
+
+ assert_shared_worker_is_loaded(
+ "../support/ping.js",
+ "Shared worker is allowed via 'strict-dynamic'");
+
+ assert_service_worker_is_loaded(
+ "../support/ping.js",
+ "Service worker is allowed via 'strict-dynamic'");
+</script>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/script-src-wildcards-disallowed.html b/testing/web-platform/tests/content-security-policy/script-src/script-src-wildcards-disallowed.html
new file mode 100644
index 0000000000..7bf3d89b67
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/script-src-wildcards-disallowed.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-nonce' *; connect-src 'self';">
+ <title>script-src disallowed wildcard use</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script nonce="nonce">
+ var t1 = async_test('data: URIs should not match *');
+ t1.step(function() {
+ var script = document.createElement("script");
+ script.src = 'data:application/javascript,';
+ script.addEventListener('load', t1.step_func(function() {
+ assert_unreached('Should not successfully load data URI.');
+ }));
+ script.addEventListener('error', t1.step_func(function() {
+ t1.done();
+ }));
+ document.head.appendChild(script);
+ });
+
+ var t2 = async_test('blob: URIs should not match *');
+ t2.step(function() {
+ var b = new Blob([''], { type: 'application/javascript' });
+ var script = document.createElement('script');
+ script.addEventListener('load', t2.step_func(function() {
+ assert_unreached('Should not successfully load blob URI.');
+ }));
+ script.addEventListener('error', t2.step_func(function() {
+ t2.done();
+ }));
+
+ script.src = URL.createObjectURL(b);
+ document.head.appendChild(script);
+ });
+
+ var t3 = async_test('filesystem URIs should not match *');
+ if (window.webkitRequestFileSystem) {
+ window.webkitRequestFileSystem(TEMPORARY, 1024*1024 /*1MB*/, function(fs) {
+ fs.root.getFile('fail.js', {create: true}, function(fileEntry) {
+ fileEntry.createWriter(function(fileWriter) {
+ var script = document.createElement('script');
+
+ script.addEventListener('load', t3.step_func(function() {
+ assert_unreached('Should not successfully load filesystem URI.');
+ }));
+ script.addEventListener('error', t3.step_func(function() {
+ t3.done();
+ }));
+
+ script.src = fileEntry.toURL('application/javascript');
+ document.body.appendChild(script);
+ });
+ });
+ });
+ } else {
+ t3.done();
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-allowed.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-allowed.sub.html
new file mode 100644
index 0000000000..8b3b45f77b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-allowed.sub.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-IFmozo9WnnsMXVl/Ka8XzJ3Nd8yzS2zA2ME0mwtd+Ck=' 'sha256-jSpTmJKcrnHttKdYM/wCCDJoQY5tdSxNf7zd2prwFfI=' 'sha256-qbgA2XjB2EZKjn/UmK7v/K77t+fvfxA89QT/K9qPNyE=' 'sha256-K+7X5Ip3msvRvyQzf6fkrWZziuhaUIee1aLnlP5nX10='; connect-src 'self';">
+ <title>scripthash-allowed</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/content-security-policy/support/alertAssert.sub.js?alerts=%5B%22PASS%20(1%2F4)%22%2C%22PASS%20(2%2F4)%22%2C%22PASS%20(3%2F4)%22%2C%22PASS%20(4%2F4)%22%5D">
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("Fail");
+ });
+ </script>
+
+ <script>
+ alert_assert('PASS (1/4)');
+
+ </script>
+ <script>
+ alert_assert('PASS (2/4)');
+
+ </script>
+ <script>
+ alert_assert('PASS (3/4)');
+
+ </script>
+ <script>
+ alert_assert('PASS (4/4)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests the effect of a valid script-hash value. It passes if no CSP violation is generated, and the alert_assert() is executed.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-base64url-converts-to-base64.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-base64url-converts-to-base64.sub.html
new file mode 100644
index 0000000000..82bf3b8622
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-base64url-converts-to-base64.sub.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta http-equiv="Content-Security-Policy"
+ content="script-src 'self'
+ 'sha256-fRoLYKuwZQJxt6FZolBE1MyQUsKFOnlf-uj65N-txt0='
+ 'sha384-vw3Q67p46tF_mKt4v6VDRTLv5Nre_boyQqppYghZpZmuy7po_KT4WSj2PF6VpNiS'
+ 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
+ ">
+ <title>Test whether hash-src are normalized from base64url to base64.</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/content-security-policy/support/alertAssert.sub.js?alerts=%5B%22PASS%20(1%2F2)%22%2C%22PASS%20(2%2F2)%22%5D"></script>
+ <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("Fail");
+ });
+ </script>
+
+ <script>
+ alert_assert('PASS (1/2)');
+
+ </script>
+ <script>
+ alert_assert('PASS (2/2)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests whether hash-src are normalized from base64url
+ to base64. It passes if no CSP violation is generated, and
+ the alert_assert() calls are executed.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked-error-event.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked-error-event.html
new file mode 100644
index 0000000000..62b869335f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked-error-event.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<head>
+ <title>CSP script-hash block causes error event</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-deadbeef'"></meta>
+</head>
+<body>
+ <script src="support/inline-script-should-be-blocked.js"></script>
+</body>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked.sub.html
new file mode 100644
index 0000000000..6bdc9f992d
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-basic-blocked.sub.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-3iveTSiUbmzN7COYvdDwyaXXzJ3SrjKlTaOvQ/GdRpo=' 'sha256-EgE/bwVJ+ZLL9F5hNjDqD4C7nlFFrdDaKeNIJ2cUem4='; connect-src 'self';">
+ <title>scripthash-basic-blocked</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../support/logTest.sub.js?logs=[]"></script>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("Fail");
+ });
+ </script>
+
+ <script>
+ var t_alert = async_test('Expecting alerts: ["PASS (1/1)"]');
+ var expected_alerts = ["PASS (1/1)"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <script>
+ alert_assert('PASS (1/1)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (1/4)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (2/4)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (3/4)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (4/4)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests the effect of a valid script-hash value, with one valid script and several invalid ones. It passes if one alert is executed and a CSP violation is reported.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-case-insensitive.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-case-insensitive.sub.html
new file mode 100644
index 0000000000..5b8f1bb823
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-case-insensitive.sub.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta http-equiv="Content-Security-Policy"
+ content="script-src 'self'
+ 'SHA256-VCOfB9NQbtW8/s+T7yizqn0dz0Ipt5krwH9BPUaXJTA='
+ 'SHA384-efOmACJwOYjUewZJTpktK4Kxl9spgncVwxok9DaIBIMN2zBzwxDni19L5uHkIX3E'
+ 'SHA512-t9CmeiAGRym+Wsi8F+5TV1QEjcbFppf7ONB9HUTOs5pMLUy3BQCmASwXD/VKl0B5QytTTJawA2IhVvoebs7Gyg=='
+ 'sHa256-BPe1cNQpEQoucXTYM91Ku9xnHT/BZXMOeOFeMZTPWis='
+ 'shA384-qNmIi2ya4g29IbFyUBBPFJ5BdkW43bygT/MrFSoe7o/ALn+a3iJDkssigmMHQ4J0'
+ 'Sha512-GuQbQFeVHDBySntDnOpbrNCe4xwjLhnnaVRAGz5JAnYK9pj0vOEAkmKgzNJApgufV3r37DE7Derx5DGUmqkukg=='
+ 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
+ ">
+ <title>Test whether hash-algorithm parts are matched case-insensitively</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/content-security-policy/support/alertAssert.sub.js?alerts=%5B%22PASS%20(1%2F6)%22%2C%22PASS%20(2%2F6)%22%2C%22PASS%20(3%2F6)%22%2C%22PASS%20(4%2F6)%22%2C%22PASS%20(5%2F6)%22%2C%22PASS%20(6%2F6)%22%5D"></script>
+ <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("Fail");
+ });
+ </script>
+
+ <script>
+ alert_assert('PASS (1/6)');
+
+ </script>
+ <script>
+ alert_assert('PASS (2/6)');
+
+ </script>
+ <script>
+ alert_assert('PASS (3/6)');
+
+ </script>
+ <script>
+ alert_assert('PASS (4/6)');
+
+ </script>
+ <script>
+ alert_assert('PASS (5/6)');
+
+ </script>
+ <script>
+ alert_assert('PASS (6/6)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests whether hash-algorithm parts are matched
+ case-insensitively. It passes if no CSP violation is generated, and
+ the alert_assert() calls are executed.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-1.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-1.html
new file mode 100644
index 0000000000..9da41dd1ef
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<head>
+ <title>CSP inline script check is done at #prepare-a-script (hash)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!--
+ 'log1 += 'scr1 at #prepare-a-script';' => 'sha256-sI+xsvqqUw0LQQGgsgkYoXKWhlGgaCqsqVbPx0Z2A4s=' (allowed)
+ 'log1 += 'scr1 at #execute-the-script-block';' => 'sha256-Vtap5AhPN9kbQAbWqObJexCvNDexqoIwo4XsABQBqcg=' (blocked)
+ -->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-sI+xsvqqUw0LQQGgsgkYoXKWhlGgaCqsqVbPx0Z2A4s='"></meta>
+</head>
+<!--
+ "Should element's inline behavior be blocked by Content Security Policy?"
+ is executed at the time of https://html.spec.whatwg.org/C/#prepare-a-script,
+ not at https://html.spec.whatwg.org/C/#execute-the-script-block.
+ So when innerText is modified after #prepare-a-script, the text BEFORE
+ the modification is used for hash check.
+-->
+<script nonce="abc">
+let log1 = '';
+</script>
+
+<!-- Execution order:
+ async script is executed
+ -> stylesheet is loaded
+ -> inline script is executed. -->
+<link rel="stylesheet" href="support/empty.css?dummy=1&pipe=trickle(d2)" type="text/css">
+<script src="support/change-scripthash-before-execute.js?dummy=1&pipe=trickle(d1)" async></script>
+<script id="scr1">log1 += 'scr1 at #prepare-a-script';</script>
+
+<script nonce="abc">
+test(() => {
+ assert_equals(log1, 'scr1 at #prepare-a-script');
+}, 'scr1.innerText before modification should not be blocked');
+</script>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-2.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-2.html
new file mode 100644
index 0000000000..927d60a8d7
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-changed-2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<head>
+ <title>CSP inline script check is done at #prepare-a-script (hash)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!--
+ 'log2 += 'scr2 at #prepare-a-script';' => 'sha256-9vE5NuHfEDoLvk3nPZPDX2/mnG+ZwKhpPuwQZwCDGc4=' (blocked)
+ 'log2 += 'scr2 at #execute-the-script-block';' => 'sha256-3AdhWTFuyxSUPxmqpTJaFRx3R5WNcyGw57lFoj1rTXw=' (allowed)
+ -->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-3AdhWTFuyxSUPxmqpTJaFRx3R5WNcyGw57lFoj1rTXw='"></meta>
+</head>
+<!--
+ "Should element's inline behavior be blocked by Content Security Policy?"
+ is executed at the time of https://html.spec.whatwg.org/C/#prepare-a-script,
+ not at https://html.spec.whatwg.org/C/#execute-the-script-block.
+ So when innerText is modified after #prepare-a-script, the text BEFORE
+ the modification is used for hash check.
+-->
+<script nonce="abc">
+let log2 = '';
+</script>
+
+<!-- Execution order:
+ async script is executed
+ -> stylesheet is loaded
+ -> inline script is executed. -->
+<link rel="stylesheet" href="support/empty.css?dummy=2&pipe=trickle(d2)" type="text/css">
+<script src="support/change-scripthash-before-execute.js?dummy=2&pipe=trickle(d1)" async></script>
+<script id="scr2">log2 += 'scr2 at #prepare-a-script';</script>
+
+<script nonce="abc">
+test(() => {
+ assert_equals(log2, '');
+}, 'scr2.innerText before modification should be blocked');
+</script>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-default-src.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-default-src.sub.html
new file mode 100644
index 0000000000..2bccf85dcd
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-default-src.sub.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'nonce-abc' 'sha256-sc3CeiHrlck5tH2tTC4MnBYFnI9D5zp8f9odqnmGQjE='; connect-src 'self';">
+ <title>script-hash allowed from default-src</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script nonce='abc'>
+ setup({ single_test: true });
+ window.addEventListener('securitypolicyviolation', function(e) {
+ assert_unreached("Should not have fired event");
+ });
+ </script>
+
+ <script>done();</script>
+ </head>
+
+ <body>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-ignore-unsafeinline.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-ignore-unsafeinline.sub.html
new file mode 100644
index 0000000000..5d3dd8b38e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-ignore-unsafeinline.sub.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'sha256-3iveTSiUbmzN7COYvdDwyaXXzJ3SrjKlTaOvQ/GdRpo=' 'sha256-EgE/bwVJ+ZLL9F5hNjDqD4C7nlFFrdDaKeNIJ2cUem4=' 'sha256-lxHfHAe5I15v8qaArcZ5WiKmLU4CjV+3tJeQUqSIWBk='; connect-src 'self';">
+
+ <title>scripthash-ignore-unsafeinline</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../support/logTest.sub.js?logs=[]"></script>
+ <script>window.addEventListener('securitypolicyviolation', function(e) { alert_assert("Fail"); })</script>
+ <script>
+ var t_alert = async_test('Expecting alerts: ["PASS (1/1)"]');
+ var expected_alerts = ["PASS (1/1)"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <script>
+ alert_assert('PASS (1/1)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (1/1)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests that a valid hash value disables inline JavaScript, even if &apos;unsafe-inline&apos; is present.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scripthash-unicode-normalization.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scripthash-unicode-normalization.sub.html
new file mode 100644
index 0000000000..b082b55e21
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scripthash-unicode-normalization.sub.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-nonceynonce' 'sha256-9UFeeZbvnMa0tLNu76v96T4Hh+UtDWHm2lPQJoTWb9c='; connect-src 'self';">
+ <title>scripthash-unicode-normalization</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+
+<body>
+ <!-- The following two scripts contain two separate code points (U+00C5
+ and U+212B, respectively) which, depending on your text editor, might be
+ rendered the same.However, their difference is important because, under
+ NFC normalization, they would become the same code point, which would be
+ against the spec. This test, therefore, validates that the scripts have
+ *different* hash values. -->
+ <script nonce="nonceynonce">
+ var t_spv = async_test("Should fire securitypolicyviolation");
+ window.addEventListener('securitypolicyviolation', t_spv.step_func_done(function(e) {
+ assert_equals(e.violatedDirective, "script-src-elem");
+ }));
+
+ var matchingContent = 'Ã…';
+ var nonMatchingContent = 'â„«';
+
+ // This script should have a hash value of
+ // sha256-9UFeeZbvnMa0tLNu76v96T4Hh+UtDWHm2lPQJoTWb9c=
+ var scriptContent1 = "window.finish('" + matchingContent + "');";
+
+ // This script should have a hash value of
+ // sha256-iNjjXUXds31FFvkAmbC74Sxnvreug3PzGtu16udQyqM=
+ var scriptContent2 = "window.finish('" + nonMatchingContent + "');";
+
+ var script1 = document.createElement('script');
+ var script2 = document.createElement('script');
+
+ script1.test = async_test("Only matching content runs even with NFC normalization.");
+
+ var failure = function() {
+ assert_unreached();
+ }
+
+ window.finish = function(content) {
+ if (content == matchingContent) {
+ script1.test.step(function() {
+ script1.test.done();
+ });
+ } else {
+ script1.test.step(function() {
+ assert_unreached("nonMatchingContent script ran");
+ });
+ }
+ }
+
+ script1.onerror = failure;
+
+ document.body.appendChild(script2);
+ script2.textContent = scriptContent2;
+ document.body.appendChild(script1);
+ script1.textContent = scriptContent1;
+ </script>
+
+ <p>
+ This tests Unicode normalization. While appearing the same, the strings in the scripts are different Unicode points, but through normalization, should be the same when the hash is taken.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-allowed.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-allowed.sub.html
new file mode 100644
index 0000000000..2cd7d646dd
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-allowed.sub.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-noncynonce' 'nonce-noncy+/nonce='; connect-src 'self';">
+ <title>scriptnonce-allowed</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script nonce="noncynonce">
+ function log(msg) {
+ test(function() {
+ assert_unreached(msg)
+ });
+ }
+
+ </script>
+ <script nonce="noncynonce">
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("Fail");
+ });
+
+ var t_alert = async_test('Expecting alerts: ["PASS (1/2)","PASS (2/2)"]');
+ var expected_alerts = ["PASS (1/2)", "PASS (2/2)"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <!-- enforcing policy:
+script-src 'self' 'unsafe-inline' 'nonce-noncynonce' 'nonce-noncy+/nonce='; connect-src 'self';
+-->
+ <script nonce="noncynonce">
+ alert_assert('PASS (1/2)');
+
+ </script>
+ <script nonce="noncy+/nonce=">
+ alert_assert('PASS (2/2)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests the effect of a valid script-nonce value. It passes if no CSP violation is generated and the alerts are executed.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-and-scripthash.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-and-scripthash.sub.html
new file mode 100644
index 0000000000..232ca052e5
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-and-scripthash.sub.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-LS8v1E1Ff0Hc8FobgWKNKY3sbW4rljPlZNQHyyutfKU=' 'nonce-nonceynonce'; connect-src 'self';">
+ <title>scriptnonce-and-scripthash</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script nonce="nonceynonce">
+ function log(msg) {
+ test(function() {
+ assert_unreached(msg)
+ });
+ }
+ </script>
+ <script nonce="nonceynonce">
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("violated-directive=" + e.violatedDirective);
+ });
+
+ var t_alert = async_test('Expecting alerts: ["PASS (1/3)","PASS (2/3)","PASS (3/3)"]');
+ var expected_alerts = ["PASS (1/3)", "PASS (2/3)", "PASS (3/3)", "violated-directive=script-src-elem", "violated-directive=script-src-elem"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <!-- enforcing policy:
+script-src 'self' 'sha256-LS8v1E1Ff0Hc8FobgWKNKY3sbW4rljPlZNQHyyutfKU=' 'nonce-nonceynonce'; connect-src 'self';
+-->
+ <script nonce="nonceynonce">
+ alert_assert('PASS (1/3)');
+
+ </script>
+ <script>
+ alert_assert('PASS (2/3)');
+
+ </script>
+ <script nonce="nonceynonce">
+ alert_assert('PASS (3/3)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (1/2)');
+
+ </script>
+ <script nonce="notanonce">
+ alert_assert('FAIL (2/2)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests the combined use of script hash and script nonce. It passes if a CSP violation is generated and the three alerts show PASS.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-basic-blocked.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-basic-blocked.sub.html
new file mode 100644
index 0000000000..2001afcd9c
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-basic-blocked.sub.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-noncynonce'; connect-src 'self';">
+ <title>scriptnonce-basic-blocked</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/alertAssert.sub.js?alerts=["PASS (closely-quoted nonce)","PASS (nonce w/whitespace)", "violated-directive=script-src-elem", "violated-directive=script-src-elem", "violated-directive=script-src-elem"]'></script>
+ <script nonce="noncynonce">
+ alert_assert('PASS (closely-quoted nonce)');
+
+ </script>
+ <script nonce=" noncynonce ">
+ alert_assert('PASS (nonce w/whitespace)');
+
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("violated-directive=" + e.violatedDirective);
+ });
+ </script>
+ <script nonce="noncynonce noncynonce">
+ alert_assert('FAIL (1/3)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (2/3)');
+
+ </script>
+ <script nonce="noncynonceno?">
+ alert_assert('FAIL (3/3)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests the effect of a valid script-nonce value. It passes if a CSP violation is generated, and the two PASS alerts are executed.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-1.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-1.html
new file mode 100644
index 0000000000..75f92f354a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-1.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<head>
+ <title>CSP inline script check is done at #prepare-a-script (nonce)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-deadbeef'"></meta>
+</head>
+<!--
+ "Should element's inline behavior be blocked by Content Security Policy?"
+ is executed at the time of https://html.spec.whatwg.org/C/#prepare-a-script,
+ not at https://html.spec.whatwg.org/C/#execute-the-script-block.
+ So when nonce is modified after #prepare-a-script, the nonce BEFORE
+ the modification is used for hash check.
+-->
+<script nonce="abc">
+let log1 = '';
+</script>
+
+<!-- Execution order:
+ async script is executed
+ -> stylesheet is loaded
+ -> inline script is executed. -->
+<link rel="stylesheet" href="support/empty.css?dummy=3&pipe=trickle(d2)" type="text/css">
+<script src="support/change-scriptnonce-before-execute.js?dummy=3&pipe=trickle(d1)" async></script>
+<script id="scr1" nonce="abc">log1 += 'scr1 executed';</script>
+
+<script nonce="abc">
+test(() => {
+ assert_equals(log1, 'scr1 executed');
+}, 'scr1 nonce before modification should not be blocked');
+</script>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-2.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-2.html
new file mode 100644
index 0000000000..f2321dd656
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-changed-2.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<head>
+ <title>CSP inline script check is done at #prepare-a-script (nonce)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc' 'sha256-deadbeef'"></meta>
+</head>
+<!--
+ "Should element's inline behavior be blocked by Content Security Policy?"
+ is executed at the time of https://html.spec.whatwg.org/C/#prepare-a-script,
+ not at https://html.spec.whatwg.org/C/#execute-the-script-block.
+ So when nonce is modified after #prepare-a-script, the nonce BEFORE
+ the modification is used for hash check.
+-->
+<script nonce="abc">
+let log2 = '';
+</script>
+
+<!-- Execution order:
+ async script is executed
+ -> stylesheet is loaded
+ -> inline script is executed. -->
+<link rel="stylesheet" href="support/empty.css?dummy=4&pipe=trickle(d2)" type="text/css">
+<script src="support/change-scriptnonce-before-execute.js?dummy=4&pipe=trickle(d1)" async></script>
+<script id="scr2" nonce="wrong">log2 += 'scr2 executed';</script>
+
+<script nonce="abc">
+test(() => {
+ assert_equals(log2, '');
+}, 'scr2 nonce before modification should be blocked');
+</script>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-ignore-unsafeinline.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-ignore-unsafeinline.sub.html
new file mode 100644
index 0000000000..6d752b3b7e
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-ignore-unsafeinline.sub.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'nonce-noncynonce' 'nonce-noncy+/nonce=' 'unsafe-inline'; connect-src 'self';">
+ <title>scriptnonce-ignore-unsafeinline</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script nonce='noncynonce'>
+ function log(msg) {
+ test(function() {
+ assert_unreached(msg)
+ });
+ }
+
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("violated-directive=" + e.violatedDirective);
+ });
+ </script>
+ <script nonce='noncynonce'>
+ var t_alert = async_test('Expecting alerts: ["PASS (1/2)","PASS (2/2)", "violated-directive=script-src-elem"]');
+ var expected_alerts = ["PASS (1/2)", "PASS (2/2)", "violated-directive=script-src-elem"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <!-- enforcing policy:
+script-src 'self' 'unsafe-inline' 'nonce-noncynonce' 'nonce-noncy+/nonce=' 'unsafe-inline'; connect-src 'self';
+-->
+ <script nonce="noncynonce">
+
+
+ </script>
+ <script nonce="noncynonce">
+ alert_assert('PASS (1/2)');
+ </script>
+ <script nonce="noncy+/nonce=">
+ alert_assert('PASS (2/2)');
+
+ </script>
+ <script>
+ alert_assert('FAIL (1/1)');
+
+ </script>
+</head>
+
+<body>
+ <p>
+ This tests that a valid nonce disables inline JavaScript, even if &apos;unsafe-inline&apos; is present.
+ </p>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-redirect.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-redirect.sub.html
new file mode 100644
index 0000000000..e659e570ee
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-redirect.sub.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'nonce-noncynonce'; connect-src 'self';">
+ <title>scriptnonce-redirect</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script nonce="noncynonce">
+ function log(msg) {
+ test(function() {
+ assert_unreached(msg)
+ });
+ }
+
+ window.addEventListener('securitypolicyviolation', function(e) {
+ alert_assert("Fail");
+ });
+ </script>
+ <script nonce="noncynonce">
+ var t_alert = async_test('Expecting alerts: ["PASS"]');
+ var expected_alerts = ["PASS"];
+
+ function alert_assert(msg) {
+ t_alert.step(function() {
+ if (msg.match(/^FAIL/i)) {
+ assert_unreached(msg);
+ t_alert.done();
+ }
+ for (var i = 0; i < expected_alerts.length; i++) {
+ if (expected_alerts[i] == msg) {
+ assert_equals(expected_alerts[i], msg);
+ expected_alerts.splice(i, 1);
+ if (expected_alerts.length == 0) {
+ t_alert.done();
+ }
+ return;
+ }
+ }
+ assert_unreached('unexpected alert: ' + msg);
+ t_log.done();
+ });
+ }
+
+ </script>
+ <!-- enforcing policy:
+script-src 'self' 'unsafe-inline' 'nonce-noncynonce'; connect-src 'self';
+-->
+</head>
+
+<body>
+ This tests whether a deferred script load caused by a redirect is properly allowed by a nonce.
+ <script nonce="noncynonce" src="/common/redirect.py?location=http://{{host}}:{{ports[http][0]}}/content-security-policy/support/alert-pass.js"></script>
+ <script nonce="noncynonce">
+
+
+ </script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html
new file mode 100644
index 0000000000..154ab68de6
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<script nonce="specified" src="/resources/testharness.js"></script>
+<script nonce="specified" src="/resources/testharnessreport.js"></script>
+
+<div id=log></div>
+<script nonce="specified">
+ [
+ {
+ name: 'CSP with both source and nonce should allow matching source',
+ src: "http://{{host}}:{{ports[http][0]}}/content-security-policy/support/alert-pass.js",
+ nonce: "notspecified"
+ },
+ {
+ name: 'CSP with both source and nonce should allow both matching nonce and source',
+ src: "http://{{host}}:{{ports[http][0]}}/content-security-policy/support/alert-pass.js",
+ nonce: "specified"
+ }
+ ].forEach(elt => {
+ async_test((test) => {
+ const s = document.createElement('script');
+ s.src = elt.src;
+ s.nonce = elt.nonce;
+ s.onload = () => test.done();
+ s.onerror = test.unreached_func('Script should load correctly');
+ document.body.appendChild(s);
+ }, elt.name);
+ });
+
+ const t = async_test('No CSP violation should fire and all scripts should load');
+ let count = 0;
+ const expected = 2;
+ function alert_assert(msg) {
+ if (msg === "PASS") {
+ count++;
+ if (count == expected) {
+ t.done();
+ }
+ }
+ }
+
+ window.addEventListener('securitypolicyviolation',
+ t.unreached_func('No CSP violation should fire'));
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html.sub.headers
new file mode 100644
index 0000000000..d23494ca83
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/scriptnonce-specified-source.sub.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: script-src {{host}}:{{ports[http][0]}} 'nonce-specified' \ No newline at end of file
diff --git a/testing/web-platform/tests/content-security-policy/script-src/simpleSourcedScript.js b/testing/web-platform/tests/content-security-policy/script-src/simpleSourcedScript.js
new file mode 100644
index 0000000000..deca86508f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/simpleSourcedScript.js
@@ -0,0 +1 @@
+window.postMessage(document.currentScript.id, "*");
diff --git a/testing/web-platform/tests/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html b/testing/web-platform/tests/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html
new file mode 100644
index 0000000000..2cae85ec30
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-abc'; connect-src 'self';">
+ <title>srcdoc-doesnt-bypass-script-src</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["violated-directive=script-src-elem"]'></script>
+</head>
+
+<body>
+
+ <script nonce='abc'>
+ window.onmessage = function(e) {
+ log(e.data);
+ }
+
+ var i = document.createElement('iframe');
+ i.addEventListener('securitypolicyviolation', function(e) {
+ log("violated-directive=" + e.violatedDirective);
+ });
+
+ i.srcdoc = "<sc" + "ript nonce='abc'>" +
+ "window.addEventListener('securitypolicyviolation', function(e) {" +
+ "window.parent.postMessage('violated-directive=' + e.violatedDirective, '*');});" +
+ "</scr" + "ipt>" +
+ "<scr" + "ipt>window.parent.log('FAIL')</scr" + "ipt>";
+ document.body.appendChild(i);
+ </script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/change-scripthash-before-execute.js b/testing/web-platform/tests/content-security-policy/script-src/support/change-scripthash-before-execute.js
new file mode 100644
index 0000000000..a04e8575b2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/change-scripthash-before-execute.js
@@ -0,0 +1,10 @@
+// This script is executed after |scr1| and |scr2| are inserted into DOM
+// before their execution (if not blocked by CSP).
+if (document.getElementById("scr1")) {
+ document.getElementById("scr1").innerText =
+ "log1 += 'scr1 at #execute-the-script-block';";
+}
+if (document.getElementById("scr2")) {
+ document.getElementById("scr2").innerText =
+ "log2 += 'scr2 at #execute-the-script-block';";
+}
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/change-scriptnonce-before-execute.js b/testing/web-platform/tests/content-security-policy/script-src/support/change-scriptnonce-before-execute.js
new file mode 100644
index 0000000000..2676b34728
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/change-scriptnonce-before-execute.js
@@ -0,0 +1,8 @@
+// This script is executed after |scr1| and |scr2| are inserted into DOM
+// before their execution (if not blocked by CSP).
+if (document.getElementById('scr1')) {
+ document.getElementById('scr1').setAttribute('nonce', 'wrong');
+}
+if (document.getElementById('scr2')) {
+ document.getElementById('scr2').setAttribute('nonce', 'abc');
+}
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/empty.css b/testing/web-platform/tests/content-security-policy/script-src/support/empty.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/empty.css
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/inject-script.js b/testing/web-platform/tests/content-security-policy/script-src/support/inject-script.js
new file mode 100644
index 0000000000..c04033c46f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/inject-script.js
@@ -0,0 +1,5 @@
+document.write("<script>log('Pass 1 of 2');</script>");
+
+var s = document.createElement('script');
+s.textContent = "log('Pass 2 of 2');";
+document.body.appendChild(s);
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/inline-script-should-be-blocked.js b/testing/web-platform/tests/content-security-policy/script-src/support/inline-script-should-be-blocked.js
new file mode 100644
index 0000000000..f32d25074b
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/inline-script-should-be-blocked.js
@@ -0,0 +1,14 @@
+var t;
+async_test(t => {
+ self.t = t;
+ const s = document.createElement('script');
+ s.onerror = t.step_func(function() {
+ assert_unreached('Script error event should not be fired.');
+ });
+ s.onload = t.step_func(function() {
+ assert_unreached('Script load event should not be fired.');
+ });
+ s.innerText = 'self.t.assert_unreached("Script should not run.");'
+ document.body.appendChild(s);
+ setTimeout(() => t.done(), 2000);
+});
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/post-message.js b/testing/web-platform/tests/content-security-policy/script-src/support/post-message.js
new file mode 100644
index 0000000000..69daa31d2f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/post-message.js
@@ -0,0 +1 @@
+postMessage("importScripts allowed");
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js b/testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js
new file mode 100644
index 0000000000..9aa87129ae
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js
@@ -0,0 +1,5 @@
+var id = 0;
+try {
+ id = eval("1 + 2 + 3");
+} catch (e) {}
+postMessage(id === 0 ? "eval blocked" : "eval allowed");
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js.sub.headers
new file mode 100644
index 0000000000..afdcc7c011
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-eval.js.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: script-src 'unsafe-inline'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js b/testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js
new file mode 100644
index 0000000000..03d9bf4cbb
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js
@@ -0,0 +1,7 @@
+var fn = function() {
+ postMessage('Function() function blocked');
+}
+try {
+ fn = new Function("", "postMessage('Function() function allowed');");
+} catch (e) {}
+fn();
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js.sub.headers
new file mode 100644
index 0000000000..afdcc7c011
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-function-function.js.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: script-src 'unsafe-inline'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js
new file mode 100644
index 0000000000..d2b6691b8a
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js
@@ -0,0 +1,17 @@
+var message = "importScripts allowed";
+try {
+ importScripts("/content-security-policy/support/post-message.js");
+} catch (e) {
+ message = "importScripts blocked";
+}
+
+if (typeof SharedWorkerGlobalScope === "function") {
+ onconnect = function (e) {
+ var port = e.ports[0];
+
+ port.onmessage = function () { port.postMessage(message); }
+ port.postMessage(message);
+ };
+} else if (typeof DedicatedWorkerGlobalScope === "function") {
+ self.postMessage(message);
+}
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js.sub.headers
new file mode 100644
index 0000000000..57616b1fc2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-importscripts.js.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: script-src 'none'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js
new file mode 100644
index 0000000000..c4241c97d0
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js
@@ -0,0 +1,16 @@
+var id = 0;
+try {
+ id = setTimeout("postMessage('handler invoked')", 100);
+} catch (e) {}
+var message = id === 0 ? "setTimeout blocked" : "setTimeout allowed";
+
+if (typeof SharedWorkerGlobalScope === "function") {
+ onconnect = function (e) {
+ var port = e.ports[0];
+
+ port.onmessage = function () { port.postMessage(message); }
+ port.postMessage(message);
+ };
+} else if (typeof DedicatedWorkerGlobalScope === "function") {
+ self.postMessage(message);
+}
diff --git a/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js.sub.headers b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js.sub.headers
new file mode 100644
index 0000000000..57616b1fc2
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/support/worker-with-script-src-none-set-timeout.js.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: script-src 'none'
diff --git a/testing/web-platform/tests/content-security-policy/script-src/worker-data-set-timeout.sub.html b/testing/web-platform/tests/content-security-policy/script-src/worker-data-set-timeout.sub.html
new file mode 100644
index 0000000000..ac4b608b08
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/worker-data-set-timeout.sub.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- We add two CSP entries on purpose. The first one does nothing
+ for the purpose of this test, but we want to check that both are
+ inherited -->
+ <meta http-equiv="Content-Security-Policy" content="object-src: 'none'">
+ <meta http-equiv="Content-Security-Policy" content="script-src data: 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>worker-data-set-timeout</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/testharness-helper.js'></script>
+</head>
+
+<body>
+ <script>
+ fetch('./support/worker-with-script-src-none-set-timeout.js')
+ .then(data => data.text())
+ .then(
+ text => assert_shared_worker_is_loaded(
+ `data:text/javascript,${text}`,
+ "Shared worker with data: url inherits CSP",
+ "setTimeout blocked"));
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/worker-eval-blocked.sub.html b/testing/web-platform/tests/content-security-policy/script-src/worker-eval-blocked.sub.html
new file mode 100644
index 0000000000..01c9eb196f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/worker-eval-blocked.sub.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>worker-eval-blocked</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["eval blocked"]'></script>
+ <script src='../support/alertAssert.sub.js?alerts=[]'></script>
+</head>
+
+<body>
+ <p>This test loads a worker, delivered with its own policy.
+ The eval() call in the worker should be forbidden by that
+ policy. No report should be generated because the worker
+ policy does not set a report-uri (although this parent
+ resource does).</p>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log('Fail');
+ });
+
+ try {
+ var worker = new Worker('/content-security-policy/script-src/support/worker-eval.js');
+ worker.onmessage = function(event) {
+ log(event.data);
+ };
+ } catch (e) {
+ log(e);
+ }
+
+ </script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/worker-function-function-blocked.sub.html b/testing/web-platform/tests/content-security-policy/script-src/worker-function-function-blocked.sub.html
new file mode 100644
index 0000000000..8c1df9f667
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/worker-function-function-blocked.sub.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>worker-function-function-blocked</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["Function() function blocked"]'></script>
+ <script src='../support/alertAssert.sub.js?alerts=[]'></script>
+</head>
+
+<body>
+ <p>This test loads a worker, delivered with its own policy.
+ The Function constructor should be forbidden by that
+ policy. No report should be generated because the worker
+ policy does not set a report-uri (although this parent
+ resource does).</p>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log('Fail');
+ });
+ try {
+ var worker = new Worker('/content-security-policy/script-src/support/worker-function-function.js');
+ worker.onmessage = function(event) {
+ log(event.data);
+ };
+ } catch (e) {
+ log(e);
+ }
+
+ </script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/worker-importscripts.sub.html b/testing/web-platform/tests/content-security-policy/script-src/worker-importscripts.sub.html
new file mode 100644
index 0000000000..ae7157cfa9
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/worker-importscripts.sub.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self';">
+ <title>worker-importscripts</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/testharness-helper.js'></script>
+</head>
+
+<body>
+ <script>
+ assert_worker_is_loaded(
+ "./support/worker-with-script-src-none-importscripts.js",
+ "Dedicated worker delivers its own CSP",
+ "importScripts blocked");
+
+ assert_shared_worker_is_loaded(
+ "./support/worker-with-script-src-none-importscripts.js",
+ "Shared worker delivers its own CSP",
+ "importScripts blocked");
+ </script>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/worker-script-src.sub.html b/testing/web-platform/tests/content-security-policy/script-src/worker-script-src.sub.html
new file mode 100644
index 0000000000..da7771b9c4
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/worker-script-src.sub.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'self';">
+ <title>worker-script-src</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/logTest.sub.js?logs=["PASS"]'></script>
+ <script src='../support/alertAssert.sub.js?alerts=[]'></script>
+</head>
+
+<body>
+ <script>
+ window.addEventListener('securitypolicyviolation', function(e) {
+ log('Fail');
+ });
+ try {
+ var foo = new Worker('/content-security-policy/script-src/support/post-message.js');
+ foo.onmessage = function(event) {
+ log("PASS");
+ };
+ } catch (e) {
+ log(e);
+ }
+
+ </script>
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/content-security-policy/script-src/worker-set-timeout.sub.html b/testing/web-platform/tests/content-security-policy/script-src/worker-set-timeout.sub.html
new file mode 100644
index 0000000000..7e73626c6f
--- /dev/null
+++ b/testing/web-platform/tests/content-security-policy/script-src/worker-set-timeout.sub.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'self' 'unsafe-eval'; connect-src 'self';">
+ <title>worker-set-timeout</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src='../support/testharness-helper.js'></script>
+</head>
+
+<body>
+ <script>
+ assert_worker_is_loaded(
+ "./support/worker-with-script-src-none-set-timeout.js",
+ "Dedicated worker delivers its own CSP",
+ "setTimeout blocked");
+
+ assert_shared_worker_is_loaded(
+ "./support/worker-with-script-src-none-set-timeout.js",
+ "Shared worker delivers its own CSP",
+ "setTimeout blocked");
+ </script>
+</body>
+
+</html>