tor-browser

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

referrer-window.html (4075B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4  <title>Worklet: Referrer</title>
      5  <script src="/common/get-host-info.sub.js"></script>
      6  <script src="/resources/testharness.js"></script>
      7  <script src="/resources/testharnessreport.js"></script>
      8  <script src="worklet-test-utils.js"></script>
      9 </head>
     10 <body>
     11 <script>
     12 function createScriptURLForTopLevel(scriptOrigin) {
     13  if (scriptOrigin === 'same')
     14    return new URL('referrer-checker.py', location.href);
     15  if (scriptOrigin === 'remote') {
     16    return new URL(get_host_info().HTTPS_REMOTE_ORIGIN +
     17                   '/worklets/resources/referrer-checker.py');
     18  }
     19  assert_unreached('scriptOrigin should be \'same\' or \'remote\'');
     20 }
     21 
     22 function createScriptURLForDecendant(scriptOrigins) {
     23  if (scriptOrigins.topLevel === 'same' &&
     24      scriptOrigins.descendant === 'same') {
     25    return new URL('import-referrer-checker-worklet-script.sub.js',
     26                   location.href);
     27  }
     28  if (scriptOrigins.topLevel === 'same' &&
     29      scriptOrigins.descendant === 'remote') {
     30    return new URL(
     31        'import-remote-origin-referrer-checker-worklet-script.sub.js',
     32        location.href);
     33  }
     34  if (scriptOrigins.topLevel === 'remote' &&
     35      scriptOrigins.descendant === 'same') {
     36    url = new URL(
     37        get_host_info().HTTPS_REMOTE_ORIGIN +
     38        '/worklets/resources/' +
     39        'import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js');
     40    return url;
     41  }
     42  if (scriptOrigins.topLevel === 'remote' &&
     43      scriptOrigins.descendant === 'remote') {
     44    return new URL(
     45        get_host_info().HTTPS_REMOTE_ORIGIN +
     46        '/worklets/resources/import-referrer-checker-worklet-script.sub.js');
     47  }
     48  assert_unreached('scriptOrigins have an invalid origin combination.');
     49 }
     50 
     51 function isDestinationCrossOrigin(fetchType, scriptOrigins) {
     52  if (fetchType === 'top-level')
     53    return scriptOrigins.topLevel === 'remote';
     54 
     55  // Compute a descendant's cross-origin-ness relative to the top-level script.
     56  if (fetchType === 'descendant')
     57    return scriptOrigins.descendant !== scriptOrigins.topLevel;
     58  assert_unreached('fetchType has an invalid value.');
     59 }
     60 
     61 function createExpectedReferrer(
     62    importerURL, fetchType, referrerPolicy, scriptOrigins) {
     63  if (referrerPolicy === 'no-referrer')
     64    return "";
     65  if (referrerPolicy === 'same-origin') {
     66    if (isDestinationCrossOrigin(fetchType, scriptOrigins))
     67      return "";
     68    // Delete query params to make it easier to match with an actual referrer in
     69    // the referrer-checker.py.
     70    const expectedReferrer = new URL(importerURL);
     71    for (var key of expectedReferrer.searchParams.keys())
     72      expectedReferrer.searchParams.delete(key);
     73    return expectedReferrer;
     74  }
     75  if (referrerPolicy === 'origin')
     76    return (new URL(importerURL)).origin + '/';
     77  assert_unreached('referrerPolicy has an invalid value.');
     78 }
     79 
     80 window.onmessage = e => {
     81  const workletType = e.data.workletType;
     82  const fetchType = e.data.fetchType;
     83  const referrerPolicy = e.data.referrerPolicy;
     84  const scriptOrigins = e.data.scriptOrigins;
     85 
     86  let scriptURL;
     87  let expectedReferrer;
     88  if (fetchType === 'top-level') {
     89    scriptURL = createScriptURLForTopLevel(scriptOrigins.topLevel);
     90    expectedReferrer = createExpectedReferrer(
     91        location.href, fetchType, referrerPolicy, scriptOrigins);
     92  } else if (fetchType === 'descendant') {
     93    scriptURL = createScriptURLForDecendant(scriptOrigins);
     94    expectedReferrer = createExpectedReferrer(
     95        scriptURL, fetchType, referrerPolicy, scriptOrigins);
     96  } else {
     97    assert_unreached('fetchType should be \'top-level\' or \'descendant\'');
     98  }
     99 
    100  const params = new URLSearchParams;
    101  params.append('requestor_origin', document.location.origin);
    102  params.append('referrer_policy', referrerPolicy);
    103  params.append('expected_referrer', expectedReferrer);
    104 
    105  get_worklet(workletType).addModule(scriptURL + '?' + params)
    106      .then(() => window.opener.postMessage('RESOLVED', '*'))
    107      .catch(e => window.opener.postMessage(e.message, '*'));
    108 };
    109 
    110 window.opener.postMessage('LOADED', '*');
    111 </script>
    112 </body>
    113 </html>