tor-browser

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

test_block_script_wrong_mime.html (5466B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <title>Bug 1288361 - Block scripts with incorrect MIME type</title>
      5  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
      8 </head>
      9 <body>
     10 
     11 <script class="testbody" type="text/javascript">
     12 
     13 const MIMETypes = [
     14  ["application/javascript", true],
     15  ["text/javascript", true],
     16 
     17  ["audio/mpeg", false],
     18  ["audio/", false],
     19  ["image/jpeg", false],
     20  ["image/", false],
     21  ["video/mpeg", false],
     22  ["video/", false],
     23  ["text/csv", false],
     24 ];
     25 
     26 // <script src="">
     27 function testScript([mime, shouldLoad]) {
     28  return new Promise((resolve) => {
     29    let script = document.createElement("script");
     30    script.onload = () => {
     31      document.body.removeChild(script);
     32      ok(shouldLoad, `script with mime '${mime}' should ${shouldLoad ? "" : "NOT "}load`);
     33      resolve();
     34    };
     35    script.onerror = () => {
     36      document.body.removeChild(script);
     37      ok(!shouldLoad, `script with wrong mime '${mime}' should be blocked`);
     38      resolve();
     39    };
     40    script.src = "file_block_script_wrong_mime_server.sjs?type=script&mime="+mime;
     41    document.body.appendChild(script);
     42  });
     43 }
     44 
     45 // new Worker()
     46 function testWorker([mime, shouldLoad]) {
     47  return new Promise((resolve) => {
     48    let worker = new Worker("file_block_script_wrong_mime_server.sjs?type=worker&mime="+mime);
     49    worker.onmessage = (event) => {
     50      ok(shouldLoad, `worker with mime '${mime}' should ${shouldLoad ? "" : "NOT "}load`);
     51      is(event.data, "worker-loaded", "worker should send correct message");
     52      resolve();
     53    };
     54    worker.onerror = (error) => {
     55      ok(!shouldLoad, `worker with wrong mime '${mime}' should be blocked`);
     56      error.preventDefault();
     57      resolve();
     58    }
     59    worker.postMessage("dummy");
     60  });
     61 }
     62 
     63 // new Worker() with importScripts()
     64 function testWorkerImportScripts([mime, shouldLoad]) {
     65  return new Promise((resolve) => {
     66    let worker = new Worker("file_block_script_wrong_mime_server.sjs?type=worker-import&mime="+mime);
     67    worker.onmessage = (event) => {
     68      ok(shouldLoad, `worker/importScripts with mime '${mime}' should ${shouldLoad ? "" : "NOT "}load`);
     69      is(event.data, "worker-loaded", "worker should send correct message");
     70      resolve();
     71    };
     72    worker.onerror = (error) => {
     73      ok(!shouldLoad, `worker/importScripts with wrong mime '${mime}' should be blocked`);
     74      error.preventDefault();
     75      resolve();
     76      // The worker doesn't self-terminate via close, so let's do it.
     77      worker.terminate();
     78    }
     79    worker.postMessage("dummy");
     80  });
     81 }
     82 
     83 async function runMimeTypePermutations() {
     84  info("### Running document script MIME checks.");
     85  for (const mimeType of MIMETypes) {
     86    await testScript(mimeType);
     87  }
     88 
     89  info("### Running worker top-level script MIME checks.");
     90  for (const mimeType of MIMETypes) {
     91    await testWorker(mimeType);
     92  }
     93 
     94  info("### Running worker importScripts MIME checks.");
     95  for (const mimeType of MIMETypes) {
     96    await testWorkerImportScripts(mimeType);
     97  }
     98 }
     99 
    100 let gRegistration;
    101 
    102 /**
    103 * Register and wait for the helper ServiceWorker to be active in the given
    104 * mode.
    105 */
    106 async function useServiceWorker({ fetchMode }) {
    107  info(`### Registering ServiceWorker with mode '${fetchMode}'`);
    108  const activePromise = new Promise((resolve, reject) => {
    109    navigator.serviceWorker.addEventListener(
    110      "message",
    111      event => {
    112        if (event.data.fetchMode === fetchMode) {
    113          resolve();
    114        } else {
    115          reject(`wrong fetchMode: ${fetchMode}`);
    116        }
    117        is(fetchMode, event.data.fetchMode, "right fetch mode");
    118      },
    119      { once: true });
    120  });
    121 
    122  const reg = gRegistration = await navigator.serviceWorker.register(
    123    `file_block_script_wrong_mime_sw.js?fetchMode=${fetchMode}`);
    124  info("register resolved. " +
    125       `installing: ${!!reg.installing} ` +
    126       `waiting: ${!!reg.waiting} ` +
    127       `active: ${!!reg.active}`);
    128 
    129  await activePromise;
    130 }
    131 
    132 /**
    133 * Unregister the ServiceWorker, with the caveat that the ServiceWorker will
    134 * still be controlling us until this window goes away.
    135 */
    136 async function cleanupServiceWorkerWithCaveat() {
    137  await gRegistration.unregister();
    138 }
    139 
    140 /**
    141 * Top-level test that runs the MIME type checks in different ServiceWorker/
    142 * network configurations.
    143 *
    144 * We use the ServiceWorker mechanism that allows ServiceWorkers to claim
    145 * existing scope-matching clients in order to make this window controlled and
    146 * then run the tests.  When changing the SW behavior the SW also needs to
    147 * skipWaiting in order to advance to active.
    148 */
    149 async function runNetworkPermutations() {
    150  await SpecialPowers.pushPrefEnv({
    151    set: [
    152      ["dom.serviceWorkers.enabled", true],
    153      ["dom.serviceWorkers.exemptFromPerDomainMax", true],
    154      ["dom.serviceWorkers.testing.enabled", true],
    155    ],
    156  });
    157 
    158  info("## Run tests without a ServiceWorker involved.");
    159  await runMimeTypePermutations();
    160 
    161  info("## Run tests with a pass-through fetch(event.request) handler.");
    162  await useServiceWorker({ fetchMode: "direct" });
    163  await runMimeTypePermutations();
    164 
    165  info("## Run tests with a naive URL propagating fetch(event.request.url) handler.");
    166  await useServiceWorker({ fetchMode: "indirect" });
    167  await runMimeTypePermutations();
    168 
    169  await cleanupServiceWorkerWithCaveat();
    170 }
    171 
    172 add_task(runNetworkPermutations);
    173 </script>
    174 </body>
    175 </html>