Skip to content

Commit faa44ea

Browse files
Yoav Weissmoz-wptsync-bot
Yoav Weiss
authored andcommitted
Bug 1935659 [wpt PR 49566] - CSP report-hash keyword for scripts, a=testonly
Automatic update from web-platform-tests CSP report-hash keyword for scripts Implement hash reporting for scripts as part of CSP. PR: w3c/webappsec-csp#693 Change-Id: Ie8d97d6094ca7601d84258cc5e1bca540eb49b39 Bug: 377830102 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6038298 Reviewed-by: Antonio Sartori <[email protected]> Commit-Queue: Yoav Weiss (@Shopify) <[email protected]> Cr-Commit-Position: refs/heads/main@{#1392854} -- wpt-commits: 22b20cf0eb577a7df17f7105e47e2b1b818d07b3 wpt-pr: 49566
1 parent f079468 commit faa44ea

22 files changed

+215
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy: default-src 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE HTML>
2+
<html>
3+
<head>
4+
<meta name="timeout" content="long">
5+
<title>Test that reports for same-origin subresources are sent with hashes</title>
6+
<script src='/resources/testharness.js'></script>
7+
<script src='/resources/testharnessreport.js'></script>
8+
<script src='/reporting/resources/report-helper.js'></script>
9+
</head>
10+
<body>
11+
<!-- Actually run the tests. -->
12+
<script src='resources/report-hash-test-runner.sub.js'></script>
13+
<script>
14+
run_tests();
15+
</script>
16+
</body>
17+
</html>
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy: script-src-elem 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Reporting-Endpoints: csp-endpoint2="/reporting/resources/report.py?reportID={{$id2:uuid()}}"
4+
Content-Security-Policy: script-src-elem 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha512'; report-to csp-endpoint2
5+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
6+
Server-Timing: uuid2;desc="{{$id2}}",hash2;desc="sha512-hG4x56V5IhUUepZdYU/lX7UOQJ2M7f6ud2EI7os4JV3OwXSZ002P3zkb9tXQkjpOO8UbtjuEufvdcU67Qt2tlw=="
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy-Report-Only: default-src 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy-Report-Only: script-src-elem 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy-Report-Only: script-src 'none' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy-Report-Only: script-src 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
function find_server_timing(name) {
2+
const server_timing = performance.getEntriesByType("navigation")[0].serverTiming;
3+
for (entry of server_timing) {
4+
if (entry.name == name) {
5+
return entry.description;
6+
}
7+
}
8+
return null;
9+
}
10+
11+
const ORIGIN = "https://{{host}}:{{ports[https][0]}}";
12+
const REMOTE_ORIGIN = "https://{{hosts[alt][www]}}:{{ports[https][0]}}";
13+
const endpoint = `${ORIGIN}/reporting/resources/report.py`;
14+
const id = find_server_timing("uuid");
15+
const id2 = find_server_timing("uuid2");
16+
const subresource_url = `${ORIGIN}/reporting/resources/comment.js`;
17+
const crossorigin_subresource_url = `${REMOTE_ORIGIN}/reporting/resources/comment.js`;
18+
const subresource_hash = find_server_timing("hash");
19+
const subresource_hash2 = find_server_timing("hash2");
20+
let counter = 0;
21+
22+
function reporting_observer_setup(expected_url, expected_hash) {
23+
return new Promise(resolve => {
24+
new ReportingObserver((reports, observer) => {
25+
assert_unreached();
26+
observer.disconnect();
27+
}, { types: ["csp-hash"] }).observe();
28+
step_timeout(resolve, 100);
29+
});
30+
}
31+
32+
async function check_reports(uuid, expected_hash, url) {
33+
const reports = await pollReports(endpoint, uuid);
34+
checkReportExists(reports, 'csp-hash', location.href);
35+
const report = getReport(reports, 'csp-hash', location.href, url);
36+
assert_not_equals(report, null);
37+
assert_equals(report.body.hash, expected_hash);
38+
assert_equals(report.body.type, "subresource");
39+
assert_equals(report.body.destination, "script");
40+
}
41+
42+
function report_hash_test(url, populate_script_attributes, expected_hash, expected_hash2, description) {
43+
promise_test(async t => {
44+
const unique_subresource_url = `${url}?${++counter}`;
45+
const observer_promise = reporting_observer_setup(unique_subresource_url, subresource_hash);
46+
// Trigger a script load
47+
await new Promise(resolve => {
48+
const script = document.createElement('script');
49+
script.src = unique_subresource_url;
50+
populate_script_attributes(script);
51+
script.addEventListener('load', resolve);
52+
document.head.appendChild(script);
53+
});
54+
55+
await check_reports(id, expected_hash, unique_subresource_url);
56+
if (id2) {
57+
await check_reports(id2, expected_hash2, unique_subresource_url);
58+
}
59+
await observer_promise;
60+
}, description);
61+
}
62+
63+
function no_report_test(create_element, description) {
64+
promise_test(async t => {
65+
const unique_subresource_url = `${subresource_url}?${++counter}`;
66+
// Trigger a script load
67+
await new Promise(resolve => {
68+
const elem = create_element(unique_subresource_url);
69+
elem.addEventListener('load', resolve);
70+
elem.addEventListener('error', resolve);
71+
document.head.appendChild(elem);
72+
});
73+
74+
// Wait for report to be received.
75+
const reports = await pollReports(endpoint, id);
76+
const report = getReport(reports, 'csp-hash', location.href, unique_subresource_url);
77+
assert_equals(report, null);
78+
}, description);
79+
};
80+
81+
function run_tests() {
82+
report_hash_test(subresource_url, script => {
83+
script.crossOrigin = "anonymous";
84+
}, subresource_hash, subresource_hash2,
85+
"Reporting endpoints received hash for same-origin CORS script.");
86+
87+
report_hash_test(subresource_url, script => {
88+
}, subresource_hash, subresource_hash2,
89+
"Reporting endpoints received hash for same-origin no-CORS script.");
90+
91+
report_hash_test(crossorigin_subresource_url, script => {
92+
script.crossOrigin = "anonymous";
93+
}, subresource_hash, subresource_hash2,
94+
"Reporting endpoints received hash for cross-origin CORS script.");
95+
96+
report_hash_test(crossorigin_subresource_url, script => {
97+
}, /*expected_hash=*/"", /*expected_hash2=*/"",
98+
"Reporting endpoints received no hash for cross-origin no-CORS script.");
99+
100+
report_hash_test(subresource_url, script => {
101+
script.crossOrigin = "anonymous";
102+
script.integrity = "sha512-hG4x56V5IhUUepZdYU/lX7UOQJ2M7f6ud2EI7os4JV3OwXSZ002P3zkb9tXQkjpOO8UbtjuEufvdcU67Qt2tlw==";
103+
}, subresource_hash, subresource_hash2,
104+
"Reporting endpoints received the right hash for same-origin CORS script with integrity.");
105+
106+
no_report_test(url => {
107+
const script = document.createElement('script');
108+
script.src = url;
109+
script.crossOrigin = "anonymous"
110+
script.integrity = "sha256-foobar";
111+
return script;
112+
}, "Reporting endpoints received no report for failed integrity check with sha256.");
113+
114+
no_report_test(url => {
115+
const script = document.createElement('script');
116+
script.src = url;
117+
script.crossOrigin = "anonymous"
118+
script.integrity = "sha512-foobar";
119+
return script;
120+
}, "Reporting endpoints received no report for failed integrity check with sha512.");
121+
122+
no_report_test(url => {
123+
const link = document.createElement('link');
124+
link.href = url;
125+
link.crossOrigin = "anonymous"
126+
link.rel = "stylesheet"
127+
return link;
128+
}, "Reporting endpoints received no report for CORS stylesheet.");
129+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy: script-src-elem 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy: script-src 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha512' 'report-sha384' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha512-hG4x56V5IhUUepZdYU/lX7UOQJ2M7f6ud2EI7os4JV3OwXSZ002P3zkb9tXQkjpOO8UbtjuEufvdcU67Qt2tlw=="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=/reporting/resources/report-helper.js
2+
// META: script=resources/report-hash-test-runner.sub.js
3+
run_tests();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID={{$id:uuid()}}"
2+
Content-Security-Policy: script-src 'self' {{hosts[alt][www]}}:{{ports[https][0]}} 'unsafe-inline' 'report-sha256'; report-to csp-endpoint
3+
Server-Timing: uuid;desc="{{$id}}",hash;desc="sha256-1XF/E08XndkoxwN6eIa5J89hYn3OVZ/UyB8BrU5jgzk="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Ceci n'est pas un commentaire
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Access-Control-Allow-Origin: *

testing/web-platform/tests/reporting/resources/report-helper.js

+9
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,12 @@ function checkReportExists(reports, type, url) {
3636
}
3737
assert_unreached(`A report of ${type} from ${url} is not found.`);
3838
}
39+
40+
function getReport(reports, type, document_url, subresource_url) {
41+
for (const report of reports) {
42+
if (report.type !== type) continue;
43+
if (report.body.documentURL === document_url && report.body.subresourceURL == subresource_url) return report;
44+
}
45+
return null;
46+
}
47+

0 commit comments

Comments
 (0)