tor-browser

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

navigate-top-to-aboutblank.https.html (6130B)


      1 <title>
      2  This tests the inheritance of COOP for navigations of the top document to about:blank.
      3 </title>
      4 <meta name=timeout content=long>
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="/common/get-host-info.sub.js"></script>
      8 <script src="/common/utils.js"></script>
      9 <script src="/common/dispatcher/dispatcher.js"></script>
     10 <script src="/html/cross-origin-opener-policy/resources/common.js"></script>
     11 
     12 
     13 <p>Non-initial empty documents (about:blank) should inherit their
     14  cross-origin-opener-policy from the navigation's initiator top level document,
     15  if the initiator and its top level document are same-origin, or default (to
     16  unsafe-none) otherwise.
     17 </p>
     18 
     19 <ol>
     20  <li>Create the opener popup with a given COOP <code>openerCOOP</code>.</li>
     21  <li>Add iframe to the opener popup that is either same-origin or
     22    cross-origin.
     23  </li>
     24  <li>Opener opens a new window, to a network document with the same origin and
     25    COOP value as opener.</li>
     26  <li>Opener's iframe navigates its parent frame (opener) to about:blank.</li>
     27  <li>Verify the openee still has access to its opener.</li>
     28 </ol>
     29 
     30 <script>
     31 const executor_path = "/common/dispatcher/executor.html?pipe=";
     32 const same_origin = get_host_info().HTTPS_ORIGIN;
     33 const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
     34 const coop_same_origin_header =
     35  '|header(Cross-Origin-Opener-Policy,same-origin)';
     36 const coop_same_origin_allow_popups_header =
     37  '|header(Cross-Origin-Opener-Policy,same-origin-allow-popups)';
     38 const coop_unsafe_none_header =
     39  '|header(Cross-Origin-Opener-Policy,unsafe-none)';
     40 
     41 function navigateToAboutBlankTest(
     42  COOP_header,
     43  iframe_origin,
     44  expect_opener_closed
     45 ){
     46  return promise_test(async t => {
     47    const this_window_token = token();
     48    const opener_token = token();
     49    const openee_token = token();
     50    const iframe_token = token();
     51 
     52    const opener_url = same_origin + executor_path + COOP_header +
     53        `&uuid=${opener_token}`;
     54    const openee_url = same_origin + executor_path + COOP_header +
     55        `&uuid=${openee_token}`;
     56    const iframe_url = iframe_origin + executor_path + `&uuid=${iframe_token}`;
     57 
     58    t.add_cleanup(() => {
     59      send(opener_token, "window.close()");
     60      send(openee_token, "window.close()");
     61    });
     62 
     63    // 1. Create the opener window.
     64    let opener_window_proxy = window.open(opener_url, opener_token);
     65 
     66    // 2. Create the iframe.
     67    send(opener_token, `
     68      iframe = document.createElement('iframe');
     69      iframe.src = "${iframe_url}";
     70      document.body.appendChild(iframe);
     71    `);
     72 
     73    // 3. The opener opens openee window.
     74    send(opener_token, `
     75      window.openee = window.open(
     76          '${openee_url.replace(/,/g, '\\,')}'
     77      );
     78    `);
     79 
     80    // 4. Ensure the popup is fully loaded.
     81    send(openee_token, `send("${this_window_token}", "Ack");`);
     82    assert_equals(await receive(this_window_token), "Ack");
     83 
     84    // 5. The iframe navigates its top-level document to about:blank. It needs
     85    // to receive a user action as it may be cross-origin and it navigates top
     86    // to a cross-origin document.
     87    // https://github.com/WICG/interventions/issues/16
     88    send(iframe_token, addScriptAndTriggerOnload(
     89      "/resources/testdriver.js",
     90      `${addScriptAndTriggerOnload("/resources/testdriver-vendor.js",
     91        `
     92        test_driver.bless('navigate top to about:blank', () => {
     93          open("about:blank", "_top");
     94        });
     95      `)}
     96    `));
     97 
     98    // 6. Ensure opener is fully loaded and then retrieve the results.
     99    send(openee_token, `
    100      (async function() {
    101        const timeout = 2000;
    102        const retry_delay = 100;
    103        for(let i = 0; i * retry_delay < timeout; ++i) {
    104          // A try-catch block is used, because of same-origin policy,
    105          // which may prevent the access to the opener if its origin changed,
    106          // after a navigation to about:blank from the cross origin iframe.
    107          try {
    108            if (
    109                window.opener === null ||
    110                window.opener.closed ||
    111                window.opener.document.location.href == "about:blank") {
    112              send("${this_window_token}", "about:blank loaded");
    113              return;
    114            }
    115          } catch(e) {
    116            // The exception is thrown when about:blank is loaded and is
    117            // cross-origin with openee.
    118            send("${this_window_token}", "about:blank loaded");
    119            return;
    120          }
    121          await new Promise(resolve => setTimeout(resolve, retry_delay));
    122        }
    123        send("${this_window_token}", "about:blank NOT loaded");
    124      })()
    125    `);
    126    assert_equals(await receive(this_window_token), "about:blank loaded");
    127 
    128    // 7. Retrieve and check the results.
    129    send(openee_token, `
    130      send(
    131        "${this_window_token}",
    132        window.opener === null || window.opener.closed);
    133    `);
    134 
    135    assert_equals(await receive(this_window_token), `${expect_opener_closed}`);
    136  }, `Navigate top to about:blank from iframe with \
    137 opener COOP: ${COOP_header}, iframe origin: ${iframe_origin}`);
    138 };
    139 
    140 // iframe same-origin with its top-level embedder:
    141 // initial empty document and about:blank navigations initiated from the
    142 // same-origin iframe will inherit COOP from the iframe's top-level embedder.
    143 
    144 // Opener's navigation to about:blank stays in the same browsing context group.
    145 navigateToAboutBlankTest(
    146  coop_same_origin_header,
    147  same_origin,
    148  false
    149 );
    150 
    151 // iframe cross-origin with its top-level embedder:
    152 // initial empty document and about:blank navigations initiated from the
    153 // cross-origin iframe will default COOP to unsafe-none.
    154 
    155 // Opener's navigation to about:blank doesn't inherit COOP, leading to a
    156 // browsing context group switch.
    157 navigateToAboutBlankTest(
    158  coop_same_origin_header,
    159  cross_origin,
    160  true
    161 );
    162 
    163 // Same origin allow popups allows the navigation of top to the cross-origin
    164 // about:blank (origin inherited from the iframe) page, which does not have COOP
    165 // (initiator is a cross origin iframe).
    166 navigateToAboutBlankTest(
    167  coop_same_origin_allow_popups_header,
    168  cross_origin,
    169  false
    170 );
    171 </script>