Source code
Revision control
Copy as Markdown
Other Tools
function find_server_timing(name) {
const server_timing = performance.getEntriesByType("navigation")[0].serverTiming;
for (entry of server_timing) {
if (entry.name == name) {
return entry.description;
}
}
return null;
}
const endpoint = `${ORIGIN}/reporting/resources/report.py`;
const id = find_server_timing("uuid");
const id2 = find_server_timing("uuid2");
const subresource_url = `${ORIGIN}/reporting/resources/comment.js`;
const crossorigin_subresource_url = `${REMOTE_ORIGIN}/reporting/resources/comment.js`;
const subresource_hash = find_server_timing("hash");
const subresource_hash2 = find_server_timing("hash2");
let counter = 0;
function reporting_observer_setup(expected_url, expected_hash) {
return new Promise(resolve => {
new ReportingObserver((reports, observer) => {
assert_unreached();
observer.disconnect();
}, { types: ["csp-hash"] }).observe();
step_timeout(resolve, 100);
});
}
async function check_reports(uuid, expected_hash, url) {
const reports = await pollReports(endpoint, uuid);
checkReportExists(reports, 'csp-hash', location.href);
const report = getReport(reports, 'csp-hash', location.href, url);
assert_not_equals(report, null);
assert_equals(report.body.hash, expected_hash);
assert_equals(report.body.type, "subresource");
assert_equals(report.body.destination, "script");
}
function report_hash_test(url, populate_script_attributes, expected_hash, expected_hash2, description) {
promise_test(async t => {
const unique_subresource_url = `${url}?${++counter}`;
const observer_promise = reporting_observer_setup(unique_subresource_url, subresource_hash);
// Trigger a script load
await new Promise(resolve => {
const script = document.createElement('script');
script.src = unique_subresource_url;
populate_script_attributes(script);
script.addEventListener('load', resolve);
document.head.appendChild(script);
});
await check_reports(id, expected_hash, unique_subresource_url);
if (id2) {
await check_reports(id2, expected_hash2, unique_subresource_url);
}
await observer_promise;
}, description);
}
function no_report_test(create_element, description) {
promise_test(async t => {
const unique_subresource_url = `${subresource_url}?${++counter}`;
// Trigger a script load
await new Promise(resolve => {
const elem = create_element(unique_subresource_url);
elem.addEventListener('load', resolve);
elem.addEventListener('error', resolve);
document.head.appendChild(elem);
});
// Wait for report to be received.
const reports = await pollReports(endpoint, id);
const report = getReport(reports, 'csp-hash', location.href, unique_subresource_url);
assert_equals(report, null);
}, description);
};
function run_tests() {
report_hash_test(subresource_url, script => {
script.crossOrigin = "anonymous";
}, subresource_hash, subresource_hash2,
"Reporting endpoints received hash for same-origin CORS script.");
report_hash_test(subresource_url, script => {
}, subresource_hash, subresource_hash2,
"Reporting endpoints received hash for same-origin no-CORS script.");
report_hash_test(crossorigin_subresource_url, script => {
script.crossOrigin = "anonymous";
}, subresource_hash, subresource_hash2,
"Reporting endpoints received hash for cross-origin CORS script.");
report_hash_test(crossorigin_subresource_url, script => {
}, /*expected_hash=*/"", /*expected_hash2=*/"",
"Reporting endpoints received no hash for cross-origin no-CORS script.");
report_hash_test(subresource_url, script => {
script.crossOrigin = "anonymous";
script.integrity = "sha512-hG4x56V5IhUUepZdYU/lX7UOQJ2M7f6ud2EI7os4JV3OwXSZ002P3zkb9tXQkjpOO8UbtjuEufvdcU67Qt2tlw==";
}, subresource_hash, subresource_hash2,
"Reporting endpoints received the right hash for same-origin CORS script with integrity.");
no_report_test(url => {
const script = document.createElement('script');
script.src = url;
script.crossOrigin = "anonymous"
script.integrity = "sha256-foobar";
return script;
}, "Reporting endpoints received no report for failed integrity check with sha256.");
no_report_test(url => {
const script = document.createElement('script');
script.src = url;
script.crossOrigin = "anonymous"
script.integrity = "sha512-foobar";
return script;
}, "Reporting endpoints received no report for failed integrity check with sha512.");
no_report_test(url => {
const link = document.createElement('link');
link.href = url;
link.crossOrigin = "anonymous"
link.rel = "stylesheet"
return link;
}, "Reporting endpoints received no report for CORS stylesheet.");
}