dynamic-integrity.html (4801B)
1 <!DOCTYPE html> 2 <html> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script type="importmap"> 6 { 7 "imports": { 8 "./resources/log.js?pipe=sub&name=ResolvesToBadHash": "./resources/log.js?pipe=sub&name=BadHash", 9 "./resources/log.js?pipe=sub&name=ResolvesToNoHash": "./resources/log.js?pipe=sub&name=NoHash", 10 "./resources/log.js?pipe=sub&name=GoodHash": "./resources/log.js?pipe=sub&name=GoodHash", 11 "bare": "./resources/log.js?pipe=sub&name=BareURL", 12 "bare2": "./resources/log.js?pipe=sub&name=F" 13 }, 14 "integrity": { 15 "./resources/log.js?pipe=sub&name=BadHash": "sha384-foobar", 16 "./resources/log.js?pipe=sub&name=ResolvesToNoHash": "sha384-foobar", 17 "./resources/log.js?pipe=sub&name=GoodHash": "sha384-SwfgBqInhSlLziU454cYhGgwPpae+d3VHZcY+vjZIO/gxRGt2u3Jsfyvure/Ww0u", 18 "./resources/log.js?pipe=sub&name=InvalidExtra": "sha384-WsKk8nzJFPhk/4pWR4LYoPhEu3xaAc6PdIm4vmqoZVWqEgMYmZgOg9XJKxgD1+8v foobar-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==", 19 "./resources/log.js?pipe=sub&name=Suffix": "sha384-lbOWldbmji7sCHI/L8iVJ+elmFIMp41p+aYOLxqQfZMqtoFeHFVe/ASRA0IyZ1/9?foobar", 20 "./resources/log.js?pipe=sub&name=Multiple": "sha384-foobar sha512-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==", 21 "./resources/log.js?pipe=sub&name=BadHashWithNoImport": "sha384-foobar", 22 "./resources/log.js?pipe=sub&name=BareURL": "sha384-foobar", 23 "./resources/log.js?pipe=sub&name=EventHandlerPass": "sha384-d4yrBK8a55vlyYz2QEnlaU64PPpdKBkblD2KmfozI61mC1ij6RrZJaGCTsVxPuJ2", 24 "./resources/log.js?pipe=sub&name=EventHandlerFail": "sha384-foobar", 25 "bare2": "sha384-foobar", 26 "resources/log.js?pipe=sub&name=Bare": "sha384-foobar" 27 } 28 } 29 </script> 30 <script> 31 let log; 32 const test_not_loaded = (url, description) => { 33 promise_test(async t => { 34 log = []; 35 await promise_rejects_js(t, TypeError, import(url)); 36 assert_array_equals(log, []); 37 }, description); 38 }; 39 40 const test_loaded = (url, log_expectation, description) => { 41 promise_test(async t => { 42 log = []; 43 await import(url); 44 assert_array_equals(log, log_expectation); 45 }, description); 46 }; 47 48 test_not_loaded( 49 "./resources/log.js?pipe=sub&name=ResolvesToBadHash", 50 "script was not loaded, as its resolved URL failed its integrity check" 51 ); 52 test_loaded( 53 "./resources/log.js?pipe=sub&name=ResolvesToNoHash", 54 ["log:NoHash"], 55 "script was loaded, as its resolved URL had no integrity check, despite its specifier having one" 56 ); 57 test_loaded( 58 "./resources/log.js?pipe=sub&name=GoodHash", 59 ["log:GoodHash"], 60 "script was loaded, as its integrity check passed" 61 ); 62 test_not_loaded( 63 "./resources/log.js?pipe=sub&name=BadHashWithNoImport", 64 "Script with no import definition was not loaded, as it failed its integrity check" 65 ); 66 test_not_loaded( 67 "bare", 68 "Bare specifier script was not loaded, as it failed its integrity check" 69 ); 70 test_loaded( 71 "bare2", 72 ["log:F"], 73 "Bare specifier used for integrity loaded, as its definition should have used the URL" 74 ); 75 test_loaded( 76 "./resources/log.js?pipe=sub&name=InvalidExtra", 77 ["log:InvalidExtra"], 78 "script was loaded, as its integrity check passed, despite having an extra invalid hash" 79 ); 80 test_loaded( 81 "./resources/log.js?pipe=sub&name=Suffix", 82 ["log:Suffix"], 83 "script was loaded, as its integrity check passed, despite having an invalid suffix" 84 ); 85 test_loaded( 86 "./resources/log.js?pipe=sub&name=Multiple", 87 ["log:Multiple"], 88 "script was loaded, as its integrity check passed given multiple hashes. This also makes sure that the larger hash is picked" 89 ); 90 test_loaded( 91 "./resources/log.js?pipe=sub&name=Bare", 92 ["log:Bare"], 93 "script was loaded, as its integrity check was ignored, as it was defined using a URL that looks like a bare specifier" 94 ); 95 96 promise_test(async () => { 97 log = []; 98 const img = new Image(); 99 const promise = new Promise((resolve, reject) => { 100 img.onload = () => { 101 import('./resources/log.js?pipe=sub&name=EventHandlerPass').then(resolve).catch(reject); 102 }; 103 img.src = "/images/green.png?1"; 104 }); 105 106 await promise; 107 assert_equals(log.length, 1); 108 assert_equals(log[0], "log:EventHandlerPass"); 109 }, "Script imported inside an event handler was loaded as its valid integrity check passed"); 110 111 promise_test(async t => { 112 log = []; 113 const img = new Image(); 114 const promise = new Promise((resolve, reject) => { 115 img.onload = () => { 116 import('./resources/log.js?pipe=sub&name=EventHandlerFail').then(resolve).catch(reject); 117 }; 118 img.src = "/images/green.png?2"; 119 }); 120 121 await promise_rejects_js(t, TypeError, promise); 122 }, "Script imported inside an event handler was not loaded as its integrity check failed"); 123 </script>