tor-browser

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

reporting-subresource-corp.tentative.https.html (5996B)


      1 <!doctype html>
      2 <html>
      3 <meta name="timeout" content="long">
      4 <body>
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="/common/dispatcher/dispatcher.js"></script>
      8 <script src="/common/utils.js"></script>
      9 <script src="/common/get-host-info.sub.js"></script>
     10 <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
     11 <script src="./resources/common.js"></script>
     12 <script>
     13 const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
     14 
     15 const header = (name, value) => `|header(${name},${value})`;
     16 const dip_reporting_header = header("document-isolation-policy", "isolate-and-require-corp") +
     17  header("document-isolation-policy-report-only", "isolate-and-require-corp");
     18 
     19 function checkReport(report, contextUrl, blockedUrl, disposition, destination) {
     20  assert_equals(report.type, 'dip');
     21  assert_equals(report.url, contextUrl);
     22  assert_equals(report.body.type, 'corp');
     23  assert_equals(report.body.blockedURL, blockedUrl);
     24  assert_equals(report.body.disposition, disposition);
     25  assert_equals(report.body.destination, destination);
     26 }
     27 
     28 function validateReports(reports, expected_count, check, context_url, resource_url) {
     29  assert_equals(reports.length, expected_count);
     30  check(reports, context_url, resource_url);
     31 }
     32 
     33 async function runRemoteContextTest(uuid, expected_count, check, context_url, resource_url) {
     34  // Have the remote context load the resource and wait for the expected number
     35  // of reports.
     36  const ctx = new RemoteContext(uuid);
     37  const reports = await ctx.execute_script(
     38    async (url, count) => {
     39      const reports_received = [];
     40 
     41      // Register an observer that will wait for reports.
     42      const receivedEveryReports = new Promise(resolve => {
     43        if (count == 0)
     44          resolve();
     45 
     46        const observer = new ReportingObserver((rs) => {
     47          for (const r of rs) {
     48            reports_received.push(r.toJSON());
     49          }
     50          if (count <= reports_received.length)
     51            resolve();
     52        });
     53        observer.observe();
     54 
     55      });
     56 
     57      // Try to fetch the resource. This might be blocked by DocumentIsolationPolicy.
     58      try {
     59        const response = await fetch(url, {mode: 'no-cors', cache: 'no-store'});
     60      } catch(error) {}
     61 
     62      await receivedEveryReports;
     63      return reports_received;
     64    }, [resource_url, expected_count]);
     65  validateReports(reports, expected_count, check, context_url, resource_url);
     66 }
     67 
     68 async function runIFrameTest(t, check, resource_url, expected_count) {
     69  // Load an iframe with DocumentIsolationPolicy reporting.
     70  const context = await createIframeContext(t, `${ORIGIN}`, dip_reporting_header);
     71  await runRemoteContextTest(context[0], expected_count, check, context[1], resource_url);
     72 }
     73 
     74 async function runDedicatedWorkerTest(t, check, resource_url, expected_count) {
     75  // Create a worker which will inherit DocumentIsolationPolicy reporting from its creator.
     76  const context = await createDedicatedWorkerContext(t, `${ORIGIN}`, dip_reporting_header);
     77  await runRemoteContextTest(context[0], expected_count, check, context[1], resource_url);
     78 }
     79 
     80 async function runSharedWorkerTest(t, check, resource_url, expected_count) {
     81  // Create a shared worker with DocumentIsolationPolicy reporting.
     82  const context = await createSharedWorkerContext(t, `${ORIGIN}`, dip_reporting_header);
     83  await runRemoteContextTest(context[0], expected_count, check, context[1], resource_url);
     84 }
     85 
     86 async function runIFrameWithServiceWorkerTest(t, check, resource_url, expected_count) {
     87  // Create an iframe with DocumentIsolationPolicy reporting and a ServiceWorker.
     88  const context = await createIframeWithSWContext(t, `${ORIGIN}`, dip_reporting_header);
     89  await runRemoteContextTest(context[0], expected_count, check, context[1], resource_url);
     90 }
     91 
     92 // We want to test several URLs in various environments (document,
     93 // dedicated worker, shared worser, service worker). As expectations
     94 // are independent of environment except for the context URLs in reports,
     95 // we define ENVIRONMENTS and CASES to reduce the code duplication.
     96 //
     97 // ENVIRONMENTS is a list of dictionaries. Each dictionary consists of:
     98 //  - tag: the name of the environment
     99 //  - run: an async function which generates reports
    100 //    - test: a testharness Test object
    101 //    - url: the URL for a test case (see below)
    102 //
    103 // CASES is a list of test cases. Each test case consists of:
    104 //  - name: the name of the test case
    105 //  - url: the URL of the test case
    106 //  - check: a function to check the results
    107 //    - reports: the generated reports
    108 //    - url: the URL of the test case
    109 //    - contextUrl: the URL of the environment settings object (see
    110 //                  ENVORONMENTS)
    111 
    112 const ENVIRONMENTS = {
    113  "document": runIFrameTest,
    114  "dedicated worker": runDedicatedWorkerTest,
    115  "shared worker": runSharedWorkerTest,
    116  "document with service worker": runIFrameWithServiceWorkerTest,
    117 };
    118 
    119 const CASES = [
    120  {
    121    name: 'same-origin',
    122    url: '/common/square.png',
    123    expected_count: 0,
    124    check: (reports, url, contextUrl) => {}
    125  },
    126  {
    127    name: 'blocked due to DIP',
    128    url: `${REMOTE_ORIGIN}/common/square.png`,
    129    expected_count: 2,
    130    check: (reports, contextUrl, url) => {
    131      checkReport(reports[0], contextUrl, url, 'reporting', '');
    132      checkReport(reports[1], contextUrl, url, 'enforce', '');
    133    }
    134  },
    135  {
    136    name: 'blocked during redirect',
    137    url: `${ORIGIN}/common/redirect.py?location=` +
    138      encodeURIComponent(`${REMOTE_ORIGIN}/common/square.png`),
    139    expected_count: 2,
    140    check: (reports, contextUrl, url) => {
    141      checkReport(reports[0], contextUrl, url, 'reporting', '');
    142      checkReport(reports[1], contextUrl, url, 'enforce', '');
    143    },
    144  }
    145 ];
    146 
    147 for (const [tag, run] of Object.entries(ENVIRONMENTS)) {
    148  for (const testcase of CASES) {
    149    promise_test(async (t) => {
    150      const reports =
    151        await run(t, testcase.check, testcase.url, testcase.expected_count);
    152    }, `[${tag}] ${testcase.name}`);
    153  }
    154 }
    155 
    156 </script>