tor-browser

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

report-hash-test-runner.sub.js (4917B)


      1 function find_server_timing(name) {
      2  const server_timing = performance.getEntriesByType("navigation")[0].serverTiming;
      3  for (entry of server_timing) {
      4    if (entry.name == name) {
      5      return entry.description;
      6    }
      7  }
      8  return null;
      9 }
     10 
     11 const ORIGIN = "https://{{host}}:{{ports[https][0]}}";
     12 const REMOTE_ORIGIN = "https://{{hosts[alt][www]}}:{{ports[https][0]}}";
     13 const endpoint = `${ORIGIN}/reporting/resources/report.py`;
     14 const id = find_server_timing("uuid");
     15 const id2 = find_server_timing("uuid2");
     16 const subresource_url = `${ORIGIN}/reporting/resources/comment.js`;
     17 const crossorigin_subresource_url = `${REMOTE_ORIGIN}/reporting/resources/comment.js`;
     18 const subresource_hash = find_server_timing("hash");
     19 const subresource_hash2 = find_server_timing("hash2");
     20 let counter = 0;
     21 
     22 function reporting_observer_setup(expected_url, expected_hash) {
     23  return new Promise(resolve => {
     24    new ReportingObserver((reports, observer) => {
     25      assert_unreached();
     26      observer.disconnect();
     27    }, { types: ["csp-hash"] }).observe();
     28    step_timeout(resolve, 100);
     29  });
     30 }
     31 
     32 async function check_reports(uuid, expected_hash, url) {
     33  const reports = await pollReports(endpoint, uuid);
     34  checkReportExists(reports, 'csp-hash', location.href);
     35  const report = getReport(reports, 'csp-hash', location.href, url);
     36  assert_not_equals(report, null);
     37  assert_equals(report.body.hash, expected_hash);
     38  assert_equals(report.body.type, "subresource");
     39  assert_equals(report.body.destination, "script");
     40 }
     41 
     42 function report_hash_test(url, populate_script_attributes, expected_hash, expected_hash2, description) {
     43  promise_test(async t => {
     44    const unique_subresource_url = `${url}?${++counter}`;
     45    const observer_promise = reporting_observer_setup(unique_subresource_url, subresource_hash);
     46    // Trigger a script load
     47    await new Promise(resolve => {
     48      const script = document.createElement('script');
     49      script.src = unique_subresource_url;
     50      populate_script_attributes(script);
     51      script.addEventListener('load', resolve);
     52      document.head.appendChild(script);
     53    });
     54 
     55    await check_reports(id, expected_hash, unique_subresource_url);
     56    if (id2) {
     57      await check_reports(id2, expected_hash2, unique_subresource_url);
     58    }
     59    await observer_promise;
     60  }, description);
     61 }
     62 
     63 function no_report_test(create_element, description) {
     64  promise_test(async t => {
     65    const unique_subresource_url = `${subresource_url}?${++counter}`;
     66    // Trigger a script load
     67    await new Promise(resolve => {
     68      const elem = create_element(unique_subresource_url);
     69      elem.addEventListener('load', resolve);
     70      elem.addEventListener('error', resolve);
     71      document.head.appendChild(elem);
     72    });
     73 
     74    // Wait for report to be received.
     75    const reports = await pollReports(endpoint, id);
     76    const report = getReport(reports, 'csp-hash', location.href, unique_subresource_url);
     77    assert_equals(report, null);
     78  }, description);
     79 };
     80 
     81 function run_tests() {
     82  report_hash_test(subresource_url, script => {
     83    script.crossOrigin = "anonymous";
     84  }, subresource_hash, subresource_hash2,
     85  "Reporting endpoints received hash for same-origin CORS script.");
     86 
     87  report_hash_test(subresource_url, script => {
     88  }, subresource_hash, subresource_hash2,
     89  "Reporting endpoints received hash for same-origin no-CORS script.");
     90 
     91  report_hash_test(crossorigin_subresource_url, script => {
     92      script.crossOrigin = "anonymous";
     93  }, subresource_hash, subresource_hash2,
     94  "Reporting endpoints received hash for cross-origin CORS script.");
     95 
     96  report_hash_test(crossorigin_subresource_url, script => {
     97  }, /*expected_hash=*/"", /*expected_hash2=*/"",
     98  "Reporting endpoints received no hash for cross-origin no-CORS script.");
     99 
    100  report_hash_test(subresource_url, script => {
    101    script.crossOrigin = "anonymous";
    102    script.integrity = "sha512-hG4x56V5IhUUepZdYU/lX7UOQJ2M7f6ud2EI7os4JV3OwXSZ002P3zkb9tXQkjpOO8UbtjuEufvdcU67Qt2tlw==";
    103  }, subresource_hash, subresource_hash2,
    104  "Reporting endpoints received the right hash for same-origin CORS script with integrity.");
    105 
    106  no_report_test(url => {
    107    const script = document.createElement('script');
    108    script.src = url;
    109    script.crossOrigin = "anonymous"
    110    script.integrity = "sha256-foobar";
    111    return script;
    112    }, "Reporting endpoints received no report for failed integrity check with sha256.");
    113 
    114  no_report_test(url => {
    115    const script = document.createElement('script');
    116    script.src = url;
    117    script.crossOrigin = "anonymous"
    118    script.integrity = "sha512-foobar";
    119    return script;
    120    }, "Reporting endpoints received no report for failed integrity check with sha512.");
    121 
    122  no_report_test(url => {
    123    const link = document.createElement('link');
    124    link.href = url;
    125    link.crossOrigin = "anonymous"
    126    link.rel = "stylesheet"
    127    return link;
    128    }, "Reporting endpoints received no report for CORS stylesheet.");
    129 }