tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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>