tor-browser

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

test_initial_blank_doc_principal.html (4315B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Tests for the principal of initial about:blank documents</title>
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
      8 </head>
      9 <body>
     10 <p id="display"></p>
     11 <div id="content"></div>
     12 <pre id="test"></pre>
     13 </body>
     14 
     15 <script>
     16  function waitForEvent(name, target, checkFn = null) {
     17    return new Promise(resolve => {
     18      function listener(event) {
     19        if (!checkFn || checkFn(event)) {
     20          resolve(event);
     21          if (checkFn) {
     22            target.removeEventListener(name, listener);
     23          }
     24        }
     25      }
     26      target.addEventListener(name, listener, { once: !checkFn });
     27    });
     28  }
     29 
     30  const testContent = document.getElementById("content");
     31 
     32  async function createSandboxedIframe(options = {}) {
     33    const { srcdoc = "", waitLoad = true, extraSandbox = "" } = options;
     34 
     35    const ifr = document.createElement("iframe");
     36    ifr.sandbox = `allow-scripts ${extraSandbox}`;
     37    if (srcdoc) {
     38      ifr.srcdoc = srcdoc;
     39    }
     40 
     41    const loaded = waitLoad ? waitForEvent("load", ifr) : null;
     42    testContent.appendChild(ifr);
     43    if (waitLoad) {
     44      await loaded;
     45    }
     46 
     47    return { ifr, doc: SpecialPowers.wrap(ifr).contentDocument };
     48  }
     49 
     50  // Tests
     51 
     52  // We want to check that
     53  // - initial about:blank documents load synchronously
     54  // - without failing assertions in nsDocShell::IsAboutBlankLoadOntoInitialAboutBlank
     55  // - while ending up with the right principal
     56 
     57  async function test_sandboxed_iframe() {
     58    // basic case: <iframe sandbox>
     59    const { ifr, doc } = await createSandboxedIframe({ waitLoad: false });
     60    is(doc.readyState, "complete", "Sandboxed iframe loaded initial document synchronously");
     61    ok(doc.nodePrincipal.isNullPrincipal, "Sandboxed ifame has null principal");
     62    ifr.remove();
     63  }
     64 
     65  async function test_nested_iframes() {
     66    // Iframes nested in an isolated iframe
     67    const { ifr } = await createSandboxedIframe({
     68      srcdoc: "<iframe id=first></iframe><iframe id=second sandbox>"
     69    });
     70 
     71    await SpecialPowers.spawn(ifr, [], () => {
     72      const origin = content.document.nodePrincipal.siteOrigin;
     73      const first = content.document.getElementById("first");
     74      const second = content.document.getElementById("second");
     75      const firstPrincipal = SpecialPowers.wrap(first).contentDocument.nodePrincipal;
     76      const secondPrincipal = SpecialPowers.wrap(second).contentDocument.nodePrincipal;
     77      ok(secondPrincipal.siteOrigin != origin, "<iframe> is implicitly isolated");
     78      ok(secondPrincipal.siteOrigin != origin, "<iframe sandbox> is explicitly isolated");
     79      ok(firstPrincipal.siteOrigin != secondPrincipal.siteOrigin, 'nested iframes are isolated from each other');
     80    });
     81 
     82    ifr.remove();
     83  }
     84 
     85  async function test_nested_iframes_crash() {
     86    // This caused an assertion failure during development
     87    // due to nsFrameLoader::Show being called for the nested frames before ReallyStartLoading
     88    // and so they end up with the wrong principal on the initial document.
     89    const { ifr } = await createSandboxedIframe({
     90      srcdoc: "<iframe id=first></iframe><iframe id=second sandbox>",
     91      extraSandbox: "allow-same-origin"
     92    });
     93    ok(true, "did not crash");
     94    ifr.remove();
     95  }
     96 
     97  async function test_sandboxed_iframe_opens_window() {
     98    // <iframe sandboxed> does window.open() which inherits the same principal
     99    const { ifr } = await createSandboxedIframe({ extraSandbox: "allow-popups" });
    100 
    101    await SpecialPowers.spawn(ifr, [], () => {
    102      const origin = content.document.nodePrincipal.siteOrigin;
    103 
    104      const popup = content.open();
    105      is(popup.document.readyState, "complete", "Popup from sandbox loaded synchronously");
    106      const popupOrigin = SpecialPowers.wrap(popup.document).nodePrincipal.siteOrigin;
    107      ok(popupOrigin != origin, "Popup from sandboxed iframe is isolated from it.");
    108 
    109      popup.close();
    110    });
    111 
    112    ifr.remove();
    113  }
    114 
    115  // Running
    116 
    117  async function tests() {
    118    SimpleTest.waitForExplicitFinish();
    119 
    120 
    121    await Promise.all([
    122      test_sandboxed_iframe(),
    123      test_nested_iframes(),
    124      test_nested_iframes_crash(),
    125      test_sandboxed_iframe_opens_window(),
    126    ]);
    127 
    128    SimpleTest.finish();
    129  }
    130 
    131  tests();
    132 </script>
    133 </html>