Skip to content

Commit 57659aa

Browse files
Yoav Weissmoz-wptsync-bot
Yoav Weiss
authored andcommitted
Bug 1948042 [wpt PR 50681] - require-sri-for: 'script', a=testonly
Automatic update from web-platform-tests require-sri-for: 'script' `require-sri-for` would enable documents to enforce SRI on all resources they load (of a certain type). This CL revives a previous attempt [1] at this that ended up being removed. It only adds the 'script' part of it, as this has a clear use case [2]. Intent-to-Prototype: https://groups.google.com/a/chromium.org/g/blink-dev/c/CdLp5BM2FCQ/m/t9ae0Do_AAAJ Spec PR: w3c/webappsec-subresource-integrity#129 [1] https://chromium-review.googlesource.com/c/chromium/src/+/2199260 [2] https://docs.google.com/document/d/1RcUpbpWPxXTyW0Qwczs9GCTLPD3-LcbbhL4ooBUevTM/edit?tab=t.0 Change-Id: I66acc12b073174cb33cf594b714e803e24656d27 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5877633 Reviewed-by: Antonio Sartori <[email protected]> Commit-Queue: Yoav Weiss (@Shopify) <[email protected]> Reviewed-by: Arthur Sonzogni <[email protected]> Cr-Commit-Position: refs/heads/main@{#1419883} -- wpt-commits: 5f473f1dcc4b545448d84c380b4a6715db612fd1 wpt-pr: 50681
1 parent a6cd20f commit 57659aa

File tree

5 files changed

+180
-1
lines changed

5 files changed

+180
-1
lines changed

testing/web-platform/tests/common/dispatcher/remote-executor.html

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
<meta charset="utf-8">
44
<body>
55
</body>
6-
<script src="./dispatcher.js"></script>
6+
<script src="./dispatcher.js"
7+
crossorigin
8+
integrity="sha256-daCATx8B9i1s6ixqZvCGcGQOv3a+VMoor6aS9UNUoiY=">
9+
</script>
710
<script>
811
const params = new URLSearchParams(window.location.search);
912
const uuid = params.get('uuid');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
window.ran = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<meta http-equiv="Content-Security-Policy" content="require-sri-for 'script'">
5+
<script>
6+
window.executed_test = async_test("Script that requires integrity executes and does not generate a violation report.");
7+
document.addEventListener('securitypolicyviolation', executed_test.unreached_func("No report should be generated."));
8+
</script>
9+
<script crossorigin integrity="sha384-tqyFpeo21WFM8HDeUtLqH20GUq/q3D1R6mqTzW3RtyTZ3dAYZJhC1wUcnkgOE2ak"
10+
src="/content-security-policy/resources/ran.js"></script>
11+
<script>
12+
assert_true(window.ran);
13+
window.executed_test.done();
14+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<meta http-equiv="Content-Security-Policy" content="require-sri-for 'script'">
5+
<script src="/content-security-policy/resources/ran.js"></script>
6+
<script>
7+
promise_test(async t => {
8+
const watcher = new EventWatcher(t, document, ['securitypolicyviolation']);
9+
const e = await watcher.wait_for('securitypolicyviolation');
10+
assert_equals(e.blockedURI, `${location.origin}/content-security-policy/resources/ran.js`);
11+
assert_true(typeof(window.ran) == "undefined", "Script did not ran");
12+
}, "Test that meta require-sri-for blocks scripts with no SRI");
13+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<!doctype html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<script src="/common/dispatcher/dispatcher.js"></script>
5+
<script src="/common/utils.js"></script>
6+
<script src="/common/get-host-info.sub.js"></script>
7+
8+
<body>
9+
<script>
10+
const {ORIGIN} = get_host_info();
11+
12+
const run_test = async (test_case) => {
13+
promise_test(async () => {
14+
const REMOTE_EXECUTOR =
15+
`/common/dispatcher/remote-executor.html?pipe=`;
16+
const iframe_uuid = token();
17+
18+
const csp_header = test_case.report_only ?
19+
"header(Content-Security-Policy-Report-Only,require-sri-for 'script')" :
20+
"header(Content-Security-Policy,require-sri-for 'script')";
21+
const iframe_url = REMOTE_EXECUTOR + encodeURIComponent(csp_header);
22+
23+
const iframe = document.createElement('iframe');
24+
iframe.src = iframe_url + `&uuid=${iframe_uuid}`;
25+
document.body.appendChild(iframe);
26+
27+
// Execute code directly from the iframe.
28+
const ctx = new RemoteContext(iframe_uuid);
29+
const result = await ctx.execute_script(async (test_case) => {
30+
let blockedURI;
31+
if (test_case.should_block) {
32+
window.addEventListener("securitypolicyviolation", e => {
33+
blockedURI = e.blockedURI;
34+
});
35+
}
36+
37+
// Load the script
38+
await new Promise(resolve => {
39+
const script = document.createElement('script');
40+
if (test_case.cross_origin) {
41+
script.crossOrigin="anonymous";
42+
}
43+
if (test_case.integrity) {
44+
script.integrity = test_case.integrity;
45+
}
46+
script.onload = resolve;
47+
script.onerror = resolve;
48+
script.src = test_case.url;
49+
document.body.appendChild(script);
50+
});
51+
52+
if (test_case.should_block && !window.ran) {
53+
return blockedURI;
54+
} else {
55+
return window.ran;
56+
}
57+
}, [test_case]);
58+
assert_equals(result, test_case.expected);
59+
}, test_case.description);
60+
};
61+
62+
const blob = new Blob([`window.ran=true;`],
63+
{ type: 'application/javascript' });
64+
65+
const blob_url = URL.createObjectURL(blob);
66+
67+
// Generated using https://sha2.it/ed25519.html (In Chrome Canary, with Experimental Web Platform Features enabled)
68+
const signature = encodeURIComponent(
69+
'header(Unencoded-Digest, sha-384=:tqyFpeo21WFM8HDeUtLqH20GUq\/q3D1R6mqTzW3RtyTZ3dAYZJhC1wUcnkgOE2ak:)' +
70+
'|header(Signature-Input, signature=\\("unencoded-digest";sf\\); keyid="JrQLj5P\/89iXES9+vFgrIy29clF9CC\/oPPsw3c5D0bs="; tag="sri")' +
71+
'|header(Signature, signature=:qM19uLskHm2TQG5LJcH/hY0n0BWWzYOJztVWYlwk0cZb3u0JdgUMre1J4Jn8Tma0x2u5/kPBfbXRMbB+X+vTBw==:)');
72+
73+
const test_cases = [
74+
{
75+
description: "Ensure that a script without integrity did not run",
76+
url: "/content-security-policy/resources/ran.js",
77+
cross_origin: true,
78+
integrity: "",
79+
should_block: true,
80+
expected: ORIGIN + "/content-security-policy/resources/ran.js",
81+
report_only: false,
82+
},
83+
{
84+
description: "Ensure that a script with unknown integrity algorithm did not run",
85+
url: "/content-security-policy/resources/ran.js",
86+
cross_origin: true,
87+
integrity: "foobar-AAAAAAAAAAAAAAAAAAAa",
88+
should_block: true,
89+
expected: ORIGIN + "/content-security-policy/resources/ran.js",
90+
report_only: false,
91+
},
92+
{
93+
description: "Ensure that a script without integrity algorithm runs and gets reported in report-only mode",
94+
url: "/content-security-policy/resources/ran.js",
95+
cross_origin: true,
96+
integrity: "",
97+
should_block: true,
98+
expected: true,
99+
report_only: true,
100+
},
101+
{
102+
description: "Ensure that a no-cors script gets blocked",
103+
url: "/content-security-policy/resources/ran.js",
104+
cross_origin: false,
105+
integrity: "sha384-tqyFpeo21WFM8HDeUtLqH20GUq/q3D1R6mqTzW3RtyTZ3dAYZJhC1wUcnkgOE2ak",
106+
should_block: true,
107+
expected: ORIGIN + "/content-security-policy/resources/ran.js",
108+
report_only: false,
109+
},
110+
{
111+
description: "Ensure that a script with integrity runs",
112+
url: "/content-security-policy/resources/ran.js",
113+
cross_origin: true,
114+
integrity: "sha384-tqyFpeo21WFM8HDeUtLqH20GUq/q3D1R6mqTzW3RtyTZ3dAYZJhC1wUcnkgOE2ak",
115+
should_block: false,
116+
expected: true,
117+
report_only: false,
118+
},
119+
{
120+
description: "Ensure that a script with signature integrity runs",
121+
url: "/content-security-policy/resources/ran.js?pipe=" + signature,
122+
cross_origin: true,
123+
integrity: "ed25519-JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=",
124+
should_block: false,
125+
expected: true,
126+
report_only: false,
127+
},
128+
{
129+
description: "Ensure that a data URI script with no integrity runs",
130+
url: "data:application/javascript,window.ran=true",
131+
cross_origin: true,
132+
integrity: "",
133+
should_block: false,
134+
expected: true,
135+
report_only: false,
136+
},
137+
{
138+
description: "Ensure that a blob URL script with no integrity runs",
139+
url: blob_url,
140+
cross_origin: true,
141+
integrity: "",
142+
should_block: false,
143+
expected: true,
144+
report_only: false,
145+
}
146+
];
147+
test_cases.map(run_test);
148+
</script>

0 commit comments

Comments
 (0)