tor-browser

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

shared-worker-import-referrer.html (10936B)


      1 <!DOCTYPE html>
      2 <title>SharedWorker: Referrer</title>
      3 <meta name="timeout" content="long" />
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script>
      7 
      8 // This Set is for checking a shared worker in each test is newly created.
      9 const existingWorkers = new Set();
     10 
     11 async function openWindow(url) {
     12  const win = window.open(url, '_blank');
     13  add_result_callback(() => win.close());
     14  const msg_event = await new Promise(resolve => window.onmessage = resolve);
     15  assert_equals(msg_event.data, 'LOADED');
     16  return win;
     17 }
     18 
     19 // Removes URL parameters from the given URL string and returns it.
     20 function removeParams(url_string) {
     21  if (!url_string)
     22    return url_string;
     23  let url = new URL(url_string);
     24  for (var key of url.searchParams.keys())
     25    url.searchParams.delete(key);
     26  return url.href;
     27 }
     28 
     29 // Generates a referrer given a fetchType, referrer policy, and a request URL
     30 // (used to determine whether request is remote-origin or not). This function
     31 // is used to generate expected referrers.
     32 function generateExpectedReferrer(referrerURL, referrerPolicy, requestURL) {
     33  let generatedReferrer = "";
     34  if (referrerPolicy === 'no-referrer')
     35    generatedReferrer = "";
     36  else if (referrerPolicy === 'origin')
     37    generatedReferrer = new URL('resources/' + referrerURL, location.href).origin + '/';
     38  else if (referrerPolicy === 'same-origin')
     39    generatedReferrer = requestURL.includes('remote') ? "" : new URL('resources/' + referrerURL, location.href).href;
     40  else
     41    generatedReferrer = new URL('resources/' + referrerURL, location.href).href;
     42 
     43  return generatedReferrer;
     44 }
     45 
     46 // Runs a referrer policy test with the given settings. This opens a new window
     47 // that starts a shared worker.
     48 //
     49 // |settings| has options as follows:
     50 //
     51 //   settings = {
     52 //     scriptURL: 'resources/referrer-checker.sub.js',
     53 //     windowReferrerPolicy: 'no-referrer',
     54 //     workerReferrerPolicy: 'same-origin',
     55 //     fetchType: 'top-level' or 'descendant-static' or 'descendant-dynamic'
     56 //   };
     57 //
     58 // - |scriptURL| is used for starting a new worker.
     59 // - |windowReferrerPolicy| is to set the ReferrerPolicy HTTP header of the
     60 //   window. This policy should be applied to top-level worker module script
     61 //   loading and static imports.
     62 // - |workerReferrerPolicy| is to set the ReferrerPolicy HTTP header of the
     63 //   worker. This policy should be applied to dynamic imports.
     64 // - |fetchType| indicates a script whose referrer will be tested.
     65 function import_referrer_test(settings, description) {
     66  promise_test(async () => {
     67    let windowURL = 'resources/new-shared-worker-window.html';
     68    if (settings.windowReferrerPolicy) {
     69      windowURL +=
     70          `?pipe=header(Referrer-Policy, ${settings.windowReferrerPolicy})`;
     71    }
     72 
     73    let scriptURL = settings.scriptURL;
     74    if (settings.workerReferrerPolicy) {
     75      // 'sub' is necessary even if the |scriptURL| contains the '.sub'
     76      // extension because the extension doesn't work with the 'pipe' parameter.
     77      // See an issue on the WPT's repository:
     78      // https://github.com/web-platform-tests/wpt/issues/9345
     79      scriptURL +=
     80          `?pipe=sub|header(Referrer-Policy, ${settings.workerReferrerPolicy})`;
     81    }
     82 
     83    const win = await openWindow(windowURL);
     84    // Construct a unique name for SharedWorker.
     85    const name = `${settings.scriptURL}_` +
     86        `${settings.windowReferrerPolicy ? settings.windowReferrerPolicy
     87                                         : settings.workerReferrerPolicy}` +
     88        `_${settings.fetchType}`;
     89    const workerProperties = { scriptURL, name };
     90    // Check if this shared worker is newly created.
     91    assert_false(existingWorkers.has(workerProperties));
     92    existingWorkers.add(workerProperties);
     93 
     94    win.postMessage(workerProperties, '*');
     95    const msgEvent = await new Promise(resolve => window.onmessage = resolve);
     96 
     97    // Generate the expected referrer, given:
     98    //   - The fetchType of the test
     99    //   - Referrer URL to be used
    100    //   - Relevant referrer policy
    101    //   - Request URL
    102    let expectedReferrer;
    103    if (settings.fetchType === 'top-level') {
    104      // Top-level worker requests have their outgoing referrers set given their
    105      // containing window's URL and referrer policy.
    106      expectedReferrer = generateExpectedReferrer('new-shared-worker-window.html', settings.windowReferrerPolicy, settings.scriptURL);
    107    } else if (settings.fetchType === 'descendant-static') {
    108      // Static descendant script requests from a worker have their outgoing
    109      // referrer set given their containing script's URL and containing
    110      // window's referrer policy.
    111 
    112      // In the below cases, the referrer URL and the request URLs are the same
    113      // because the initial request (for the top-level worker script) should
    114      // act as the referrer for future descendant requests.
    115      expectedReferrer = generateExpectedReferrer(settings.scriptURL, settings.windowReferrerPolicy, settings.scriptURL);
    116    } else if (settings.fetchType === 'descendant-dynamic') {
    117      // Dynamic descendant script requests from a worker have their outgoing
    118      // referrer set given their containing script's URL and referrer policy.
    119      expectedReferrer = generateExpectedReferrer(settings.scriptURL, settings.workerReferrerPolicy, settings.scriptURL);
    120    }
    121 
    122    // Delete query parameters from the actual referrer to make it easy to match
    123    // it with the expected referrer.
    124    const actualReferrer = removeParams(msgEvent.data);
    125 
    126    assert_equals(actualReferrer, expectedReferrer);
    127  }, description);
    128 }
    129 
    130 // Tests for top-level worker module script loading.
    131 //
    132 // Top-level worker module scripts should inherit the containing window's
    133 // referrer policy when using the containing window's URL as the referrer.
    134 //
    135 // [Current document]
    136 // --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|.
    137 //   --(new SharedWorker)--> [SharedWorker] should respect [windowReferrerPolicy|
    138 //                           when using [Window]'s URL as the referrer.
    139 
    140 import_referrer_test(
    141    { scriptURL: 'postmessage-referrer-checker.py',
    142      windowReferrerPolicy: 'no-referrer',
    143      fetchType: 'top-level' },
    144    'Same-origin top-level module script loading with "no-referrer" referrer ' +
    145        'policy');
    146 
    147 import_referrer_test(
    148    { scriptURL: 'postmessage-referrer-checker.py',
    149      windowReferrerPolicy: 'origin',
    150      fetchType: 'top-level' },
    151    'Same-origin top-level module script loading with "origin" referrer ' +
    152        'policy');
    153 
    154 import_referrer_test(
    155    { scriptURL: 'postmessage-referrer-checker.py',
    156      windowReferrerPolicy: 'same-origin',
    157      fetchType: 'top-level' },
    158    'Same-origin top-level module script loading with "same-origin" referrer ' +
    159        'policy');
    160 
    161 // Tests for static imports.
    162 //
    163 // Static imports should inherit the containing window's referrer policy when
    164 // using the containing module script's URL as the referrer.
    165 // Note: This is subject to change in the future; see
    166 // https://github.com/w3c/webappsec-referrer-policy/issues/111.
    167 //
    168 // [Current document]
    169 // --(open)--> [Window] whose referrer policy is |windowReferrerPolicy|.
    170 //   --(new SharedWorker)--> [SharedWorker]
    171 //     --(static import)--> [Script] should respect |windowReferrerPolicy| when
    172 //                          using [SharedWorker]'s URL as the referrer.
    173 
    174 import_referrer_test(
    175    { scriptURL: 'static-import-same-origin-referrer-checker-worker.js',
    176      windowReferrerPolicy: 'no-referrer',
    177      fetchType: 'descendant-static' },
    178    'Same-origin static import with "no-referrer" referrer policy.');
    179 
    180 import_referrer_test(
    181    { scriptURL: 'static-import-same-origin-referrer-checker-worker.js',
    182      windowReferrerPolicy: 'origin',
    183      fetchType: 'descendant-static' },
    184    'Same-origin static import with "origin" referrer policy.');
    185 
    186 import_referrer_test(
    187    { scriptURL: 'static-import-same-origin-referrer-checker-worker.js',
    188      windowReferrerPolicy: 'same-origin',
    189      fetchType: 'descendant-static' },
    190    'Same-origin static import with "same-origin" referrer policy.');
    191 
    192 import_referrer_test(
    193    { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js',
    194      windowReferrerPolicy: 'no-referrer',
    195      fetchType: 'descendant-static' },
    196    'Cross-origin static import with "no-referrer" referrer policy.');
    197 
    198 import_referrer_test(
    199    { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js',
    200      windowReferrerPolicy: 'origin',
    201      fetchType: 'descendant-static' },
    202    'Cross-origin static import with "origin" referrer policy.');
    203 
    204 import_referrer_test(
    205    { scriptURL: 'static-import-remote-origin-referrer-checker-worker.sub.js',
    206      windowReferrerPolicy: 'same-origin',
    207      fetchType: 'descendant-static' },
    208    'Cross-origin static import with "same-origin" referrer policy.');
    209 
    210 // Tests for dynamic imports.
    211 //
    212 // Dynamic imports should inherit the containing script's referrer policy if
    213 // set, and use the default referrer policy otherwise, when using the
    214 // containing script's URL as the referrer.
    215 //
    216 // [Current document]
    217 // --(open)--> [Window]
    218 //   --(new SharedWorker)--> [SharedWorker] whose referrer policy is
    219 //                           |workerReferrerPolicy|.
    220 //     --(dynamic import)--> [Script] should respect |workerReferrerPolicy| when
    221 //                           using [SharedWorker]'s URL as the referrer.
    222 
    223 import_referrer_test(
    224    { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js',
    225      workerReferrerPolicy: 'no-referrer',
    226      fetchType: 'descendant-dynamic' },
    227    'Same-origin dynamic import with "no-referrer" referrer policy.');
    228 
    229 import_referrer_test(
    230    { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js',
    231      workerReferrerPolicy: 'origin',
    232      fetchType: 'descendant-dynamic' },
    233    'Same-origin dynamic import with "origin" referrer policy.');
    234 
    235 import_referrer_test(
    236    { scriptURL: 'dynamic-import-same-origin-referrer-checker-worker.js',
    237      workerReferrerPolicy: 'same-origin',
    238      fetchType: 'descendant-dynamic' },
    239    'Same-origin dynamic import with "same-origin" referrer policy.');
    240 
    241 import_referrer_test(
    242    { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js',
    243      workerReferrerPolicy: 'no-referrer',
    244      fetchType: 'descendant-dynamic' },
    245    'Cross-origin dynamic import with "no-referrer" referrer policy.');
    246 
    247 import_referrer_test(
    248    { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js',
    249      workerReferrerPolicy: 'origin',
    250      fetchType: 'descendant-dynamic' },
    251    'Cross-origin dynamic import with "origin" referrer policy.');
    252 
    253 import_referrer_test(
    254    { scriptURL: 'dynamic-import-remote-origin-referrer-checker-worker.sub.js',
    255      workerReferrerPolicy: 'same-origin',
    256      fetchType: 'descendant-dynamic' },
    257    'Cross-origin dynamic import with "same-origin" referrer policy.');
    258 
    259 </script>