tor-browser

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

document-state.https.html (6160B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>Test the properties of a session history entry's document state</title>
      4 <link rel="help" href="https://html.spec.whatwg.org/#document-state">
      5 <script src="/common/dispatcher/dispatcher.js"></script>
      6 <script src="/common/get-host-info.sub.js"></script>
      7 <script src="/common/utils.js"></script>
      8 <script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script>
      9 <script src="/resources/testharness.js"></script>
     10 <script src="/resources/testharnessreport.js"></script>
     11 
     12 <body>
     13 <script>
     14 // In this test, we create an auxiliary window with a session history A -> B,
     15 // where the document on site B is the current active document. Bf-cache is
     16 // disabled via `Cache-Control: no-store` headers. We then `history.back()` to
     17 // site A, and perform `location.replace(B)`. This makes the first document in
     18 // the session history now same-origin/site with the URL in the subsequent
     19 // session history entry's document state.
     20 //
     21 // We then perform `history.forward()` in the first document, which loads the
     22 // second document (from network). We confirm that the resulting navigation
     23 // request was made with the expected state, stored on the history entry's
     24 // document state. The consequences of this are:
     25 //  - The navigation is made with the `Sec-Fetch-Site: cross-site` header,
     26 //    indicating that the *original* document state's initiator origin was
     27 //    preserved
     28 //  - The navigation is made with a cross-origin `Referer` header, indicating
     29 //    that the *original* document state's referrer was preserved
     30 //  - The resulting document has a cross-origin `document.referrer`, indicating
     31 //    the same as above
     32 promise_test(async t => {
     33  const rcHelper = new RemoteContextHelper();
     34  const A = await rcHelper.addWindow();
     35 
     36  // Create B on a new origin (with bf-cache disabled).
     37  const B = await A.navigateToNew({
     38    origin: 'HTTPS_NOTSAMESITE_ORIGIN',
     39    headers: [['Cache-Control', 'no-store']],
     40  });
     41 
     42  // This is the origin we're going to navigate A to, so that it becomes
     43  // same-origin with B.
     44  const originB = new URL(await B.executeScript(() => location.href)).origin;
     45  await B.historyBack();
     46 
     47  // Make A navigate to the same document but in origin B:
     48  const urlA = await A.executeScript(() => location.href);
     49  const originA = new URL(urlA).origin;
     50  assert_not_equals(originA, originB, 'Contexts A and B are cross-origin');
     51 
     52  // Load A's current document but on origin B.
     53  const newUrlOnOriginB = urlA.replace(originA, originB);
     54  await A.navigate((url) => {
     55    location.replace(url);
     56  }, [newUrlOnOriginB]);
     57 
     58  // Assert that A and B are now same-origin:
     59  const newUrlA = await A.executeScript(() => {
     60    return location.href;
     61  });
     62 
     63  // Now the session history looks like:
     64  // B -> B (initiator origin: A)
     65  assert_equals(new URL(newUrlA).origin, originB);
     66 
     67  // This means that when we navigate forward, we should request the second
     68  // document with the history entry's document state, which mostly preserves
     69  // parameters from the original initiator (a cross-site document), despite a
     70  // now-same-origin document initiating this navigation via history.
     71  await A.historyForward();
     72 
     73  const requestHeaders = await B.getRequestHeaders();
     74  const documentReferrer = await B.executeScript(() => document.referrer);
     75 
     76  assert_equals(requestHeaders.get('sec-fetch-site'), 'cross-site',
     77      'Same-origin forward history navigation to a document whose original ' +
     78      'initiator was cross-site, ends up with Sec-Fetch-Dest: cross-site ' +
     79      'header');
     80  assert_equals(requestHeaders.get('referer'), originA + '/',
     81      'Same-origin forward history navigation to a document whose original ' +
     82      'initiator was cross-site ends up with the Referer header that is the ' +
     83      'original cross-site initiator');
     84  assert_equals(documentReferrer, originA + '/',
     85      'Same-origin forward history navigation to a document whose original ' +
     86      'initiator was cross-site ends up with document.referrer that is the ' +
     87      'original cross-site initiator');
     88 }, "A navigation's initiator origin and referrer are stored in the document " +
     89   "state and used in the document repopulation case");
     90 
     91 // This test is similar to the above, but instead of testing for the true
     92 // history entry -> document state -> document repopulation case, we stay on [B]
     93 // (the document who was navigated to from [A]) and run `location.reload()` to
     94 // confirm that the initiator information from the [A] -> [B] navigation is used
     95 // when reloading [B], not [B]'s own same-origin information.
     96 promise_test(async t => {
     97  const rcHelper = new RemoteContextHelper();
     98  const A = await rcHelper.addWindow();
     99 
    100  const originA = new URL(await A.executeScript(() => location.href)).origin;
    101 
    102  // Create B on a new origin.
    103  const B = await A.navigateToNew({
    104    origin: 'HTTPS_NOTSAMESITE_ORIGIN',
    105  });
    106 
    107  const originB = new URL(await B.executeScript(() => location.href)).origin;
    108  assert_not_equals(originA, originB, 'Contexts A and B are cross-origin');
    109 
    110  // Reload B.
    111  await B.navigate(() => {
    112    location.reload();
    113  }, []);
    114 
    115  const requestHeaders = await B.getRequestHeaders();
    116  const documentReferrer = await B.executeScript(() => document.referrer);
    117 
    118  assert_equals(requestHeaders.get('sec-fetch-site'), 'cross-site',
    119      'Same-origin forward history navigation to a document whose original ' +
    120      'initiator was cross-site, ends up with Sec-Fetch-Dest: cross-site ' +
    121      'header');
    122  assert_equals(requestHeaders.get('referer'), originA + '/',
    123      'Same-origin forward history navigation to a document whose original ' +
    124      'initiator was cross-site ends up with the Referer header that is the ' +
    125      'original cross-site initiator');
    126  assert_equals(documentReferrer, originA + '/',
    127      'Same-origin forward history navigation to a document whose original ' +
    128      'initiator was cross-site ends up with document.referrer that is the ' +
    129      'original cross-site initiator');
    130 }, "A navigation's initiator origin and referrer are stored in the document " +
    131   "state and used on location.reload()");
    132 </script>
    133 </body>