tor-browser

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

testharness-helper.sub.js (5546B)


      1 const Host = {
      2  SAME_ORIGIN: "same-origin",
      3  CROSS_ORIGIN: "cross-origin",
      4 };
      5 
      6 const PolicyHeader = {
      7  CSP: "echo-policy.py?policy=",
      8  CSP_MULTIPLE: "echo-policy-multiple.py",
      9  REQUIRED_CSP: "echo-required-csp.py",
     10  ALLOW_CSP_FROM: "echo-allow-csp-from.py",
     11 };
     12 
     13 const IframeLoad = {
     14  EXPECT_BLOCK: true,
     15  EXPECT_LOAD: false,
     16 };
     17 
     18 function getOrigin() {
     19  var url = new URL("http://{{host}}:{{ports[http][0]}}/");
     20  return url.origin;
     21 }
     22 
     23 function getCrossOrigin() {
     24  var url = new URL("http://{{domains[天気の良い日]}}:{{ports[http][0]}}/");
     25  return url.toString();
     26 }
     27 
     28 function getSecureCrossOrigin() {
     29  // Since wptserve spins up servers on non-default port, 'self' matches
     30  // http://[host]:[specified-port] and https://[host]:[specified-port], but not
     31  // https://[host]:[https-port]. So, we use the http port for this https origin
     32  // in order to verify that a secure variant of a non-secure URL matches 'self'.
     33  var url = new URL("https://{{domains[天気の良い日]}}:{{ports[http][0]}}");
     34  return url.toString();
     35 }
     36 
     37 function generateURL(host, path, include_second_level_iframe, second_level_iframe_csp) {
     38  var url = new URL("http://{{host}}:{{ports[http][0]}}/content-security-policy/embedded-enforcement/support/");
     39  url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}";
     40  url.pathname += path;
     41  if (include_second_level_iframe) {
     42    url.searchParams.append("include_second_level_iframe", "");
     43    if (second_level_iframe_csp)
     44      url.searchParams.append("second_level_iframe_csp", second_level_iframe_csp);
     45  }
     46 
     47  return url;
     48 }
     49 
     50 function generateURLString(host, path) {
     51  return generateURL(host, path, false, "").toString();
     52 }
     53 
     54 function generateURLStringWithSecondIframeParams(host, path, second_level_iframe_csp) {
     55  return generateURL(host, path, true, second_level_iframe_csp).toString();
     56 }
     57 
     58 function generateRedirect(host, target) {
     59  var url = new URL("http://{{host}}:{{ports[http][0]}}/common/redirect.py?location=" +
     60   encodeURIComponent(target));
     61  url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}";
     62 
     63  return url.toString();
     64 }
     65 
     66 function generateUrlWithPolicies(host, policy) {
     67  var url = generateURL(host, PolicyHeader.CSP_MULTIPLE);
     68  if (policy != null)
     69    url.searchParams.append("policy", policy);
     70  return url;
     71 }
     72 
     73 function generateUrlWithAllowCSPFrom(host, allowCspFrom) {
     74  var url = generateURL(host, PolicyHeader.ALLOW_CSP_FROM);
     75  if (allowCspFrom != null)
     76    url.searchParams.append("allow_csp_from", allowCspFrom);
     77  return url;
     78 }
     79 
     80 function assert_required_csp(t, url, csp, expected) {
     81  var i = document.createElement('iframe');
     82  if(csp)
     83    i.csp = csp;
     84  i.src = url;
     85 
     86  window.addEventListener('message', t.step_func(e => {
     87    if (e.source != i.contentWindow || !('required_csp' in e.data))
     88      return;
     89 
     90    if (expected.indexOf(e.data['required_csp']) == -1)
     91      assert_unreached('Child iframes have unexpected csp:"' + e.data['required_csp'] + '"');
     92 
     93    expected.splice(expected.indexOf(e.data['required_csp']), 1);
     94 
     95    if (e.data['test_header_injection'] != null)
     96      assert_unreached('HTTP header injection was successful');
     97 
     98    if (expected.length == 0)
     99      t.done();
    100  }));
    101 
    102  document.body.appendChild(i);
    103 }
    104 
    105 function assert_iframe_with_csp(t, url, csp, shouldBlock, urlId, blockedURI,
    106                                checkImageLoaded) {
    107  const i = document.createElement('iframe');
    108  url.searchParams.append("id", urlId);
    109  i.src = url.toString();
    110  if (csp != null)
    111    i.csp = csp;
    112 
    113  if (shouldBlock) {
    114    // Assert iframe does not load and is inaccessible.
    115    window.addEventListener("message", t.step_func(function(e) {
    116      if (e.source != i.contentWindow) return;
    117      assert_unreached('No message should be sent from the frame.');
    118    }));
    119    i.onload = t.step_wait_func_done(function() {
    120      if (!i.contentWindow) return false;
    121      try {
    122        let x = i.contentWindow.location.href;
    123        return false;
    124      } catch (e) {
    125        return true;
    126      }
    127    }, t.step_func(() => {
    128      assert_throws_dom("SecurityError", () => {
    129        let x = i.contentWindow.location.href;
    130      });
    131    }), "The error frame should be cross-origin.", 5000, 500);
    132  } else {
    133    let successPromises = [];
    134 
    135    let loadPromise = new Promise(resolve => {
    136      i.onload = resolve;
    137    });
    138    successPromises.push(loadPromise);
    139 
    140    let loadMsgPromise = new Promise(resolve => {
    141      window.addEventListener("message", function (e) {
    142        if (e.source != i.contentWindow) return;
    143        if (e.data["loaded"] && e.data["id"] === urlId) resolve();
    144      });
    145    });
    146    successPromises.push(loadMsgPromise);
    147 
    148    if (blockedURI) {
    149      let securityViolationPromise = new Promise(resolve => {
    150        window.addEventListener('message', t.step_func(e => {
    151          if (e.source != i.contentWindow) return;
    152          if (!e.data.securitypolicyviolation) return;
    153          assert_equals(e.data["blockedURI"], blockedURI);
    154          resolve();
    155        }));
    156      });
    157      successPromises.push(securityViolationPromise);
    158    }
    159 
    160    if (checkImageLoaded) {
    161      let imageLoadedPromise = new Promise(resolve => {
    162        window.addEventListener('message', e => {
    163          if (e.source != i.contentWindow) return;
    164          if (e.data === "img loaded") resolve();
    165        });
    166      });
    167      successPromises.push(imageLoadedPromise);
    168    }
    169 
    170    // Wait for all promises to resolve.
    171    Promise.all(successPromises).then(t.step_func_done());
    172  }
    173  document.body.appendChild(i);
    174 }