tor-browser

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

connect-src-self.sub.js (4756B)


      1 importScripts("{{location[server]}}/resources/testharness.js");
      2 importScripts("{{location[server]}}/content-security-policy/support/testharness-helper.js");
      3 
      4 let base_same_origin_url =
      5      "{{location[server]}}/content-security-policy/support/resource.py";
      6 let base_cross_origin_url =
      7      "https://{{hosts[][www]}}:{{ports[https][1]}}" +
      8      "/content-security-policy/support/resource.py";
      9 
     10 // Same-origin
     11 promise_test(t => {
     12  let url = `${base_same_origin_url}?same-origin-fetch`;
     13  assert_no_csp_event_for_url(t, url);
     14 
     15  return fetch(url)
     16    .then(t.step_func(r => assert_equals(r.status, 200)));
     17 }, "Same-origin 'fetch()' in " + self.location.protocol +
     18             " with {{GET[test-name]}}");
     19 
     20 // XHR is not available in service workers.
     21 if (self.XMLHttpRequest) {
     22  promise_test(t => {
     23    let url = `${base_same_origin_url}?same-origin-xhr`;
     24    assert_no_csp_event_for_url(t, url);
     25 
     26    return new Promise((resolve, reject) => {
     27      let xhr = new XMLHttpRequest();
     28      xhr.open("GET", url);
     29      xhr.onload = resolve;
     30      xhr.onerror = _ => reject("xhr.open should success.");
     31      xhr.send();
     32    });
     33  }, "Same-origin XHR in " + self.location.protocol +
     34               " with {{GET[test-name]}}");
     35 }
     36 
     37 let fetch_cross_origin_url = `${base_cross_origin_url}?cross-origin-fetch`;
     38 
     39 // Cross-origin
     40 promise_test(t => {
     41  let url = fetch_cross_origin_url;
     42 
     43  return Promise.all([
     44    waitUntilCSPEventForURL(t, url),
     45    fetch(url)
     46        .then(t.step_func(_ => assert_unreached(
     47            "cross-origin fetch should have thrown.")))
     48        .catch(t.step_func(e => assert_true(e instanceof TypeError)))
     49  ]);
     50 }, "Cross-origin 'fetch()' in " + self.location.protocol +
     51             " with {{GET[test-name]}}");
     52 
     53 let xhr_cross_origin_url = `${base_cross_origin_url}?cross-origin-xhr`;
     54 
     55 // XHR is not available in service workers.
     56 if (self.XMLHttpRequest) {
     57  promise_test(t => {
     58    let url = xhr_cross_origin_url;
     59 
     60    return Promise.all([
     61      waitUntilCSPEventForURL(t, url),
     62      new Promise((resolve, reject) => {
     63        let xhr = new XMLHttpRequest();
     64        xhr.open("GET", url);
     65        xhr.onload = _ => reject("xhr.open should have thrown.");
     66        xhr.onerror = resolve;
     67        xhr.send();
     68      })
     69    ]);
     70  }, "Cross-origin XHR in " + self.location.protocol +
     71               " with {{GET[test-name]}}");
     72 }
     73 
     74 let redirect_url = `{{location[server]}}/common/redirect-opt-in.py?` +
     75      `status=307&location=${fetch_cross_origin_url}`;
     76 
     77 // Same-origin redirecting to cross-origin
     78 promise_test(t => {
     79  let url = redirect_url;
     80 
     81  return Promise.all([
     82    waitUntilCSPEventForURL(t, url),
     83    fetch(url)
     84        .then(t.step_func(_ => assert_unreached(
     85            "cross-origin redirect should have thrown.")))
     86      .catch(t.step_func(e => assert_true(e instanceof TypeError)))
     87  ]);
     88 }, "Same-origin => cross-origin 'fetch()' in " + self.location.protocol +
     89             " with {{GET[test-name]}}");
     90 
     91 
     92 let websocket_url = "wss://{{host}}:{{ports[wss][0]}}/echo";
     93 
     94 // The WebSocket URL is not the same as 'self'
     95 promise_test(t => {
     96  return Promise.all([
     97    waitUntilCSPEventForURL(t, websocket_url),
     98    new Promise((resolve, reject) => {
     99      // Firefox throws in the constructor, Chrome triggers the error event.
    100      try {
    101        let ws = new WebSocket(websocket_url);
    102        ws.onerror = resolve;
    103        ws.onopen = reject; // unexpected
    104      } catch (e) {
    105        resolve();
    106      }
    107    })
    108  ]);
    109 }, "WebSocket in " + self.location.protocol + " with {{GET[test-name]}}");
    110 
    111 let expected_blocked_urls = self.XMLHttpRequest
    112    ? [ fetch_cross_origin_url, xhr_cross_origin_url, redirect_url, websocket_url ]
    113    : [ fetch_cross_origin_url, redirect_url, websocket_url ];
    114 
    115 promise_test(async t => {
    116  let report_url = `{{location[server]}}/reporting/resources/report.py` +
    117      `?op=retrieve_report&reportID={{GET[id]}}` +
    118      `&min_count=${expected_blocked_urls.length}`;
    119 
    120  let response = await fetch(report_url);
    121  assert_equals(response.status, 200, "Fetching reports failed");
    122 
    123  let response_json = await response.json();
    124  let reports = response_json.map(x => x["csp-report"]);
    125 
    126  assert_array_equals(
    127      reports.map(x => x["blocked-uri"]).sort(),
    128      expected_blocked_urls.sort(),
    129      "Reports do not match");
    130  reports.forEach(x => {
    131    assert_equals(
    132        x["violated-directive"], "connect-src",
    133        "Violated directive in report does not match");
    134    assert_equals(
    135        x["effective-directive"], "connect-src",
    136        "Effective directive in report does not match");
    137    assert_equals(
    138        x["disposition"], "enforce",
    139        "Effective directive in report does not match");
    140  });
    141 }, "Reports match in " + self.location.protocol + " with {{GET[test-name]}}");
    142 
    143 done();