tor-browser

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

worker-in-sandboxed-iframe-by-csp-fetch-event.https.html (4746B)


      1 <!DOCTYPE html>
      2 <title>ServiceWorker FetchEvent issued from workers in an iframe sandboxed via CSP HTTP response header.</title>
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script src="resources/test-helpers.sub.js"></script>
      6 <body>
      7 <script>
      8 let lastCallbackId = 0;
      9 let callbacks = {};
     10 function doTest(frame, type) {
     11  return new Promise(function(resolve) {
     12    var id = ++lastCallbackId;
     13    callbacks[id] = resolve;
     14    frame.contentWindow.postMessage({id: id, type: type}, '*');
     15  });
     16 }
     17 
     18 // Asks the service worker for data about requests and clients seen. The
     19 // worker posts a message back with |data| where:
     20 // |data.requests|: the requests the worker received FetchEvents for
     21 // |data.clients|: the URLs of all the worker's clients
     22 // The worker clears its data after responding.
     23 function getResultsFromWorker(worker) {
     24  return new Promise(resolve => {
     25    let channel = new MessageChannel();
     26    channel.port1.onmessage = msg => {
     27      resolve(msg.data);
     28    };
     29    worker.postMessage({port: channel.port2}, [channel.port2]);
     30  });
     31 }
     32 
     33 window.onmessage = function (e) {
     34  message = e.data;
     35  let id = message['id'];
     36  let callback = callbacks[id];
     37  delete callbacks[id];
     38  callback(message['result']);
     39 };
     40 
     41 const SCOPE = 'resources/sandboxed-iframe-fetch-event-iframe.py';
     42 const SCRIPT = 'resources/sandboxed-iframe-fetch-event-worker.js';
     43 const expected_base_url = new URL(SCOPE, location.href);
     44 // A service worker controlling |SCOPE|.
     45 let worker;
     46 // An iframe whose response header has
     47 // 'Content-Security-Policy: allow-scripts'.
     48 // This should NOT be controlled by a service worker.
     49 let sandboxed_frame_by_header;
     50 // An iframe whose response header has
     51 // 'Content-Security-Policy: allow-scripts allow-same-origin'.
     52 // This should be controlled by a service worker.
     53 let sandboxed_same_origin_frame_by_header;
     54 
     55 promise_test(t => {
     56  return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
     57    .then(function(registration) {
     58      add_completion_callback(() => registration.unregister());
     59      worker = registration.installing;
     60      return wait_for_state(t, registration.installing, 'activated');
     61    });
     62 }, 'Prepare a service worker.');
     63 
     64 promise_test(t => {
     65  const iframe_full_url = expected_base_url + '?sandbox=allow-scripts&' +
     66                          'sandboxed-frame-by-header';
     67  return with_iframe(iframe_full_url)
     68    .then(f => {
     69      sandboxed_frame_by_header = f;
     70      add_completion_callback(() => f.remove());
     71      return getResultsFromWorker(worker);
     72    })
     73    .then(data => {
     74      let requests = data.requests;
     75      assert_equals(requests.length, 1,
     76                    'Service worker should provide the response');
     77      assert_equals(requests[0], iframe_full_url);
     78      assert_false(data.clients.includes(iframe_full_url),
     79                   'Service worker should NOT control the sandboxed page');
     80    });
     81 }, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts.');
     82 
     83 promise_test(t => {
     84  const iframe_full_url =
     85    expected_base_url + '?sandbox=allow-scripts%20allow-same-origin&' +
     86    'sandboxed-iframe-same-origin-by-header';
     87  return with_iframe(iframe_full_url)
     88    .then(f => {
     89      sandboxed_same_origin_frame_by_header = f;
     90      add_completion_callback(() => f.remove());
     91      return getResultsFromWorker(worker);
     92    })
     93    .then(data => {
     94      let requests = data.requests;
     95      assert_equals(requests.length, 1);
     96      assert_equals(requests[0], iframe_full_url);
     97      assert_true(data.clients.includes(iframe_full_url));
     98    })
     99 }, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts and ' +
    100   'allow-same-origin.');
    101 
    102 promise_test(t => {
    103  let frame = sandboxed_frame_by_header;
    104  return doTest(frame, 'fetch-from-worker')
    105    .then(result => {
    106      assert_equals(result, 'done');
    107      return getResultsFromWorker(worker);
    108    })
    109    .then(data => {
    110      assert_equals(data.requests.length, 0,
    111                    'The request should NOT be handled by SW.');
    112    });
    113 }, 'Fetch request from a worker in iframe sandboxed by CSP HTTP header ' +
    114   'allow-scripts flag');
    115 
    116 promise_test(t => {
    117  let frame = sandboxed_same_origin_frame_by_header;
    118  return doTest(frame, 'fetch-from-worker')
    119    .then(result => {
    120      assert_equals(result, 'done');
    121      return getResultsFromWorker(worker);
    122    })
    123    .then(data => {
    124      let requests = data.requests;
    125      assert_equals(requests.length, 1,
    126                    'The request should be handled by SW.');
    127      assert_equals(requests[0], frame.src + '&test=fetch-from-worker');
    128    });
    129 }, 'Fetch request from a worker in iframe sandboxed by CSP HTTP header ' +
    130   'with allow-scripts and allow-same-origin flag');
    131 </script>
    132 </body>