script-nonces-hidden-meta.sub.html (4741B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 5 <meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; img-src 'none'"> 6 7 <body> 8 <!-- Basics --> 9 <script nonce="abc" id="testScript"> 10 document.currentScript.setAttribute('executed', 'yay'); 11 </script> 12 13 <script nonce="abc"> 14 var script = document.querySelector('#testScript'); 15 16 test(t => { 17 // Query Selector 18 assert_equals(document.querySelector('body [nonce]'), script); 19 assert_equals(document.querySelector('body [nonce=""]'), null); 20 assert_equals(document.querySelector('body [nonce=abc]'), script); 21 22 assert_equals(script.getAttribute('nonce'), 'abc'); 23 assert_equals(script.nonce, 'abc'); 24 }, "Reading 'nonce' content attribute and IDL attribute."); 25 26 // Clone node. 27 test(t => { 28 script.setAttribute('executed', 'boo'); 29 var s2 = script.cloneNode(); 30 assert_equals(s2.nonce, 'abc', 'IDL attribute'); 31 assert_equals(s2.getAttribute('nonce'), 'abc'); 32 }, "Cloned node retains nonce."); 33 34 async_test(t => { 35 var s2 = script.cloneNode(); 36 document.head.appendChild(s2); 37 assert_equals(s2.nonce, 'abc'); 38 assert_equals(s2.getAttribute('nonce'), 'abc'); 39 window.addEventListener('load', t.step_func_done(_ => { 40 // The cloned script won't execute, as its 'already started' flag is set. 41 assert_equals(s2.getAttribute('executed'), 'boo'); 42 })); 43 }, "Cloned node retains nonce when inserted."); 44 45 // Set the content attribute to 'foo' 46 test(t => { 47 script.setAttribute('nonce', 'foo'); 48 assert_equals(script.getAttribute('nonce'), 'foo'); 49 assert_equals(script.nonce, 'foo'); 50 }, "Writing 'nonce' content attribute."); 51 52 // Set the IDL attribute to 'bar' 53 test(t => { 54 script.nonce = 'bar'; 55 assert_equals(script.nonce, 'bar'); 56 assert_equals(script.getAttribute('nonce'), 'foo'); 57 }, "Writing 'nonce' IDL attribute."); 58 59 // Fragment parser. 60 var documentWriteTest = async_test("Document-written script executes."); 61 document.write(`<script nonce='abc'> 62 documentWriteTest.done(); 63 test(t => { 64 var script = document.currentScript; 65 assert_equals(script.getAttribute('nonce'), 'abc'); 66 assert_equals(script.nonce, 'abc'); 67 }, "Document-written script's nonce value."); 68 </scr` + `ipt>`); 69 70 // Create node. 71 async_test(t => { 72 var s = document.createElement('script'); 73 s.innerText = script.innerText; 74 s.nonce = 'abc'; 75 assert_equals(s.nonce, 'abc'); 76 assert_equals(s.getAttribute('nonce'), null); 77 document.head.appendChild(s); 78 assert_equals(s.nonce, 'abc'); 79 assert_equals(s.getAttribute('nonce'), null); 80 81 window.addEventListener('load', t.step_func_done(_ => { 82 assert_equals(s.getAttribute('executed'), 'yay'); 83 })); 84 }, "createElement.nonce."); 85 86 async_test(t => { 87 var s = document.createElement('script'); 88 s.innerText = script.innerText; 89 s.nonce = 'zyx'; 90 s.setAttribute('nonce', 'abc'); 91 assert_equals(s.nonce, 'abc'); 92 document.head.appendChild(s); 93 assert_equals(s.nonce, 'abc'); 94 assert_equals(s.getAttribute('nonce'), 'abc'); 95 96 window.addEventListener('load', t.step_func_done(_ => { 97 assert_equals(s.getAttribute('executed'), 'yay'); 98 })); 99 }, "setAttribute('nonce') overwrites '.nonce' upon insertion."); 100 101 // Create node. 102 async_test(t => { 103 var s = document.createElement('script'); 104 s.innerText = script.innerText; 105 s.setAttribute('nonce', 'abc'); 106 assert_equals(s.getAttribute('nonce'), 'abc', "Pre-insertion content"); 107 assert_equals(s.nonce, 'abc', "Pre-insertion IDL"); 108 document.head.appendChild(s); 109 assert_equals(s.nonce, 'abc', "Post-insertion IDL"); 110 assert_equals(s.getAttribute('nonce'), 'abc', "Post-insertion content"); 111 112 window.addEventListener('load', t.step_func_done(_ => { 113 assert_equals(s.getAttribute('executed'), 'yay'); 114 })); 115 }, "createElement.setAttribute."); 116 </script> 117 118 <!-- CSS Leakage --> 119 <style> 120 #cssTest { display: block; } 121 #cssTest[nonce=abc] { background: url(/security/resources/abe.png); } 122 </style> 123 <script nonce="abc" id="cssTest"> 124 test(t => { 125 const script = document.querySelector('#cssTest'); 126 t.add_cleanup(() => script.remove()); 127 var style = getComputedStyle(script); 128 assert_equals(style['display'], 'block'); 129 assert_equals(style['background-image'], "url(\"http://{{domains[]}}:{{ports[http][0]}}/security/resources/abe.png\")"); 130 }, "Nonces leak via CSS side-channels."); 131 </script>