script.window.js (4503B)
1 // META: script=/common/subset-tests-by-key.js 2 // META: variant=?include=integrity-none 3 // META: variant=?include=integrity-pass 4 // META: variant=?include=integrity-fail 5 // META: timeout=long 6 7 // Given `{ digest: "...", body: "...", cors: true }`: 8 function scriptURL(data) { 9 data.type = "application/javascript"; 10 let params = new URLSearchParams(data); 11 return "./resource.py?" + params.toString(); 12 } 13 14 const executable_body = "window.hello = `world`;"; 15 const unreached_body = "assert_unreached(`This code should not execute.`);"; 16 const executable_hashes = { 17 "sha-256": "PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=", 18 "sha-512": "6qaEeboWnnFooKiwqnorS3SbkLk5rZcqoSsgEeB97srB0WIH6hJk2QDevHAen7gym6/jW244Ogf5MhZMjPYFrA==" 19 }; 20 const well_formed_but_incorrect_hashes = { 21 "sha-256": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", 22 "sha-512": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" 23 }; 24 25 const EXPECT_BLOCKED = "block"; 26 const EXPECT_LOADED = "loaded"; 27 function generate_test(data, expectation, desc) { 28 subsetTestByKey("integrity-none", async_test, t => { 29 let s = document.createElement('script'); 30 s.src = scriptURL(data); 31 if (expectation == EXPECT_BLOCKED) { 32 s.onerror = t.step_func_done(e => { 33 assert_equals("error", e.type); 34 }); 35 s.onload = t.unreached_func("Script should not execute."); 36 } else { 37 s.onload = t.step_func_done(e => { 38 assert_equals("load", e.type); 39 }); 40 s.onerror = t.unreached_func("Script should not fail."); 41 } 42 document.body.appendChild(s); 43 }, "No `integrity` attribute + " + desc); 44 45 subsetTestByKey("integrity-pass", async_test, t => { 46 let s = document.createElement('script'); 47 s.src = scriptURL(data); 48 s.crossorigin = "anonymous"; 49 s.integrity = `sha256-${executable_hashes['sha-256']}` 50 if (expectation == EXPECT_BLOCKED) { 51 s.onerror = t.step_func_done(e => { 52 assert_equals("error", e.type); 53 }); 54 s.onload = t.unreached_func("Script should not execute."); 55 } else { 56 s.onload = t.step_func_done(e => { 57 assert_equals("load", e.type); 58 }); 59 s.onerror = t.unreached_func("Script should not fail."); 60 } 61 document.body.appendChild(s); 62 }, "Matching `integrity` attribute + " + desc); 63 64 subsetTestByKey("integrity-fail", async_test, t => { 65 let s = document.createElement('script'); 66 s.src = scriptURL(data); 67 s.crossorigin = "anonymous"; 68 s.integrity = `sha512-${well_formed_but_incorrect_hashes['sha-512']}` 69 s.onerror = t.step_func_done(e => { 70 assert_equals("error", e.type); 71 }); 72 s.onload = t.unreached_func("Script should not execute."); 73 document.body.appendChild(s); 74 }, "Mismatching `integrity` attribute always blocks: " + desc); 75 } 76 77 // No header. 78 generate_test( 79 { body: executable_body }, 80 EXPECT_LOADED, 81 "No header: loads."); 82 83 let good_header_list = []; 84 let bad_header_list = []; 85 let mixed_header_list = []; 86 for (const key in executable_hashes) { 87 let good_header = `${key}=:${executable_hashes[key]}:`; 88 good_header_list.push(good_header); 89 let bad_header = `${key}=:${well_formed_but_incorrect_hashes[key]}:`; 90 bad_header_list.push(bad_header); 91 mixed_header_list.push(good_header, bad_header); 92 93 // - Good single headers: 94 generate_test({ 95 body: executable_body, 96 digest: good_header 97 }, 98 EXPECT_LOADED, 99 `Good ${key} header: loads.`); 100 101 // - Good multiple headers: 102 generate_test({ 103 body: executable_body, 104 digest: `${good_header},${good_header}` 105 }, 106 EXPECT_LOADED, 107 `Repeated ${key} header: loads.`); 108 109 generate_test({ 110 body: executable_body, 111 digest: good_header_list.join(",") 112 }, 113 EXPECT_LOADED, 114 `Multiple good headers (previous += ${key}): loads.`); 115 116 // - Bad single headers: 117 generate_test({ 118 body: executable_body, 119 digest: bad_header 120 }, 121 EXPECT_BLOCKED, 122 `Bad ${key} header: blocked.`); 123 124 // - Bad multiple headers: 125 generate_test({ 126 body: executable_body, 127 digest: `${bad_header},${bad_header}` 128 }, 129 EXPECT_BLOCKED, 130 `Repeated ${key} header: blocked.`); 131 132 generate_test({ 133 body: executable_body, 134 digest: bad_header_list.join(",") 135 }, 136 EXPECT_BLOCKED, 137 `Multiple bad headers (previous += ${key}): blocked.`); 138 } 139 140 // - Mixed headers. 141 generate_test({ 142 body: executable_body, 143 digest: mixed_header_list.join(","), 144 }, 145 EXPECT_BLOCKED, 146 `Mixed good and bad headers: blocked.`);