tor-browser

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

test-case.sub.js (4247B)


      1 // https://w3c.github.io/webappsec-referrer-policy/#strip-url
      2 function stripUrlForUseAsReferrer(url, originOnly) {
      3  // Step 2. If url’s scheme is a local scheme, then return no referrer.
      4  const parsedUrl = new URL(url);
      5 
      6  if (["about:", "blob:", "data:"].includes(parsedUrl.protocol))
      7    return undefined;
      8 
      9  // Step 3. Set url’s username to the empty string.
     10  parsedUrl.username = '';
     11 
     12  // Step 4. Set url’s password to null.
     13  parsedUrl.password = '';
     14 
     15  // Step 5. Set url’s fragment to null.
     16  parsedUrl.hash = '';
     17 
     18  //  Step 6. If the origin-only flag is true, then:
     19  if (originOnly) {
     20    // Step 6.1. Set url’s path to null.
     21    parsedUrl.pathname = '';
     22    // Step 6.2. Set url’s query to null.
     23    parsedUrl.search = '';
     24  }
     25  return parsedUrl.href;
     26 }
     27 
     28 function invokeScenario(scenario) {
     29  const urls = getRequestURLs(
     30    scenario.subresource,
     31    scenario.origin,
     32    scenario.redirection);
     33  /** @type {Subresource} */
     34  const subresource = {
     35    subresourceType: scenario.subresource,
     36    url: urls.testUrl,
     37    policyDeliveries: scenario.subresource_policy_deliveries,
     38  };
     39 
     40  return invokeRequest(subresource, scenario.source_context_list);
     41 }
     42 
     43 const referrerUrlResolver = {
     44  // The spec allows UAs to "enforce arbitrary policy considerations in the
     45  // interests of minimizing data leakage"; to start to vaguely approximate
     46  // this, we allow stronger policies to be used instead of what's specificed.
     47  "omitted": function(sourceUrl) {
     48    return [undefined];
     49  },
     50  "origin": function(sourceUrl) {
     51    return [stripUrlForUseAsReferrer(sourceUrl, true),
     52            undefined];
     53  },
     54  "stripped-referrer": function(sourceUrl) {
     55    return [stripUrlForUseAsReferrer(sourceUrl, false),
     56            stripUrlForUseAsReferrer(sourceUrl, true),
     57            undefined];
     58  }
     59 };
     60 
     61 function checkResult(scenario, expectation, result) {
     62 // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
     63  let referrerSource = result.sourceContextUrl;
     64  const sentFromSrcdoc = scenario.source_context_list.length > 0 &&
     65      scenario.source_context_list[scenario.source_context_list.length - 1]
     66      .sourceContextType === 'srcdoc';
     67  if (sentFromSrcdoc) {
     68    // Step 3. While document is an iframe srcdoc document, let document be
     69    // document's browsing context's browsing context container's node
     70    // document. [spec text]
     71 
     72    // Workaround for srcdoc cases. Currently we only test <iframe srcdoc>
     73    // inside the top-level Document, so |document| in the spec here is
     74    // the top-level Document.
     75    // This doesn't work if e.g. we test <iframe srcdoc> inside another
     76    // external <iframe>.
     77    referrerSource = location.toString();
     78  }
     79  const possibleReferrerUrls =
     80    referrerUrlResolver[expectation](referrerSource);
     81 
     82  // Check the reported URL.
     83  assert_in_array(result.referrer,
     84                  possibleReferrerUrls,
     85                  "document.referrer");
     86  assert_in_array(result.headers.referer,
     87                  possibleReferrerUrls,
     88                  "HTTP Referer header");
     89 }
     90 
     91 function runLengthTest(scenario, urlLength, expectation, testDescription) {
     92  // `Referer` headers with length over 4k are culled down to an origin, so,
     93  // let's test around that boundary for tests that would otherwise return
     94  // the complete URL.
     95  history.pushState(null, null, "/");
     96  history.replaceState(null, null,
     97      "A".repeat(urlLength - location.href.length));
     98 
     99  promise_test(t => {
    100    assert_equals(scenario.expectation, "stripped-referrer");
    101    // Only on top-level Window, due to navigations using `history`.
    102    assert_equals(scenario.source_context_list.length, 0);
    103 
    104    return invokeScenario(scenario)
    105      .then(result => checkResult(scenario, expectation, result));
    106  }, testDescription);
    107 }
    108 
    109 function TestCase(scenarios, sanityChecker) {
    110  function runTest(scenario) {
    111    // This check is A NOOP in release.
    112    sanityChecker.checkScenario(scenario);
    113 
    114    promise_test(_ => {
    115      return invokeScenario(scenario)
    116        .then(result => checkResult(scenario, scenario.expectation, result));
    117    }, scenario.test_description);
    118  }
    119 
    120  function runTests() {
    121    for (const scenario of scenarios) {
    122      runTest(scenario);
    123    }
    124  }
    125 
    126  return {start: runTests};
    127 }