tor-browser

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

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>