report-hash-test-runner.sub.js (4917B)
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 }