tor-browser

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

window-open-blank-from-different-initiator.html (3686B)


      1 <meta name="timeout" content="long">
      2 <script src="/resources/testharness.js"></script>
      3 <script src="/resources/testharnessreport.js"></script>
      4 <script src="/common/get-host-info.sub.js"></script>
      5 <script src="/common/utils.js"></script>
      6 <script>
      7 
      8 // This is a regression test for https://crbug.com/1170038.
      9 //
     10 // A document creates a popup and makes it navigate elsewhere. The navigation
     11 // will never commit. The popup has not completed any real load outside of the
     12 // initial empty document. Then from a different window with a different CSP
     13 // policy, make it navigate to about:blank.
     14 //
     15 // Web browser behavior might change depending on whether a pending navigation
     16 // exists for in the popup or not. Both are tested here.
     17 
     18 const same_origin = get_host_info().HTTP_ORIGIN;
     19 
     20 // Return a promise, resolving when |element| triggers |event_name| event.
     21 const future = (element, event_name) => {
     22  return new Promise(resolve => element.addEventListener(event_name, resolve));
     23 };
     24 
     25 // `createNewPopup` is a function returning a new window that has not committed
     26 // any real load in its frame, outside of the initial empty document. The two
     27 // tests below vary depending on whether there is a pending navigation in the
     28 // frame or not.
     29 const runTest = (description, createNewPopup) => {
     30  promise_test(async test => {
     31    // Open a same-origin window with a different CSP.
     32    const executor_path =
     33      "/html/browsers/sandboxing/resources/execute-postmessage.html?pipe=";
     34    const csp = "|header(Content-Security-Policy, " +
     35                "sandbox" +
     36                " allow-scripts" +
     37                " allow-popups" +
     38                " allow-same-origin" +
     39                " allow-popups-to-escape-sandbox";
     40    const executor = window.open(same_origin + executor_path + csp);
     41    const executor_reply = await future(window, "message");
     42    assert_equals(executor_reply.data, "ready");
     43 
     44    const popup_name = token();
     45    const popup = await createNewPopup(test, popup_name);
     46 
     47    // Request the first real load from a DIFFERENT window with different CSPs.
     48    const first_real_load = future(popup, "load");
     49    executor.postMessage(`window.open("about:blank", "${popup_name}");`);
     50    await first_real_load;
     51 
     52    // The new blank document in the popup must inherit CSPs from |executor|:
     53    let is_sandboxed = future(window, "message");
     54    popup.document.write(`
     55      <script>
     56        try {
     57          document.domain = document.domain;
     58          opener.opener.postMessage("not sandboxed", "*");
     59        } catch (error) {
     60          opener.opener.postMessage("sandboxed", "*");
     61        }
     62      </scr`+`ipt>
     63    `);
     64    assert_equals((await is_sandboxed).data, "sandboxed");
     65  }, description);
     66 }
     67 
     68 // Open a new window and start loading from an unresponsive server. The frame
     69 // will be left with the initial empty document and a pending navigation.
     70 runTest("One pending navigation", async (test, popup_name) => {
     71  const unresponsive_path = "/common/slow.py?delay=1000000";
     72  return window.open(same_origin + unresponsive_path, popup_name);
     73 });
     74 
     75 // Open a new window and start loading. The response is a 204 and the navigation
     76 // is canceled. As a result, the frame will be left with the initial empty
     77 // document and NO pending navigation.
     78 runTest("No pending navigation", async (test, popup_name) => {
     79  const no_content_path = "/common/blank.html?pipe=status(204)"
     80  const popup = window.open(same_origin + no_content_path, popup_name);
     81 
     82  // Unfortunately, there are no web API to detect a navigation has been
     83  // canceled. Waiting using setTimeout is the only possible way to wait for it.
     84  await new Promise(r => test.step_timeout(r, 1000));
     85 
     86  return popup;
     87 });
     88 
     89 </script>