tor-browser

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

service-worker-cache-storage.https.html (4390B)


      1 <!doctype html>
      2 <html>
      3 <title> Check enforcement of COEP in a ServiceWorker using CacheStorage. </title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script src="/common/get-host-info.sub.js"></script>
      7 <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
      8 <script>
      9 // See also: ./dedicated-worker-cache-storage.https.html
     10 
     11 function remote(path) {
     12  const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
     13  return new URL(path, REMOTE_ORIGIN);
     14 }
     15 
     16 const iframe_path = "./resources/iframe.html?pipe=";
     17 const service_worker_path = "./resources/universal-worker.js?pipe=";
     18 const ressource_path = "/images/blue.png?pipe=";
     19 
     20 const coep_header= {
     21  "coep-none"         : "",
     22  "coep-require-corp" : "|header(Cross-Origin-Embedder-Policy,require-corp)",
     23 }
     24 
     25 const corp_header = {
     26  "corp-undefined"    : "",
     27  "corp-cross-origin" : "|header(Cross-Origin-Resource-Policy,cross-origin)",
     28 }
     29 
     30 // Send a message to the |worker| and wait for its response.
     31 function executeCommandInServiceWorker(worker, command) {
     32  const channel = new MessageChannel();
     33  const response = new Promise(resolve => channel.port1.onmessage = resolve);
     34  worker.postMessage(command, [ channel.port2 ]);
     35  return response;
     36 }
     37 
     38 // Check enforcement of COEP in a ServiceWorker using CacheStorage.
     39 //
     40 // 1) Fetch a response from a document with COEP:none. Store it in the
     41 //    CacheStorage. The response is cross-origin without any CORS header.
     42 // 2) From a ServiceWorker, retrieve the response from the CacheStorage.
     43 //
     44 // Test parameters:
     45 // - |worker_coep| the COEP header of the ServiceWorker's script response.
     46 // - |response_corp| the CORP header of the response.
     47 //
     48 // Test expectations:
     49 // |loaded| is true whenever the worker is able to fetch the response from
     50 // the CacheStorage. According to the specification:
     51 // https://mikewest.github.io/corpp/#initialize-embedder-policy-for-global
     52 // it must be false when:
     53 // - |worker_coep| is 'coep-require-corp' and
     54 // - |response-corp| is 'corp-undefined'.
     55 function check(
     56  // Test parameters:
     57  worker_coep,
     58  response_corp,
     59 
     60  // Test expectations:
     61  loaded) {
     62 
     63  promise_test(async (t) => {
     64    // 1) Fetch a response from a document with COEP:none. Store it in the
     65    //    CacheStorage. The response is cross-origin without any CORS header.
     66    const resource_path = ressource_path + corp_header[response_corp];
     67    const resource_url = remote(resource_path);
     68    const fetch_request = new Request(resource_url, {mode: 'no-cors'});
     69    const cache = await caches.open('v1');
     70    const fetch_response = await fetch(fetch_request);
     71    await cache.put(fetch_request, fetch_response);
     72 
     73    // 2) Start a ServiceWorker.
     74    const SCOPE= new URL(location.href).pathname;
     75    const service_worker_allowed = `|header(service-worker-allowed,${SCOPE})`;
     76    const SCRIPT =
     77      service_worker_path +
     78      coep_header[worker_coep] +
     79      service_worker_allowed;
     80 
     81    const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE);
     82    add_completion_callback(() => reg.unregister());
     83 
     84    // Start talking to the ServiceWorker, no matter its state.
     85    const worker = reg.installing || reg.waiting || reg.active;
     86 
     87    // 3) From the service worker, try to retrieve the response from the
     88    //    CacheStorage.
     89    const response = executeCommandInServiceWorker(worker, `
     90      (async function() {
     91        const cache = await caches.open('v1');
     92        const request = new Request('${resource_url}', {
     93          mode: 'no-cors'
     94        });
     95        try {
     96          const response = await cache.match(request);
     97          message.ports[0].postMessage('success');
     98        } catch(error) {
     99          message.ports[0].postMessage('error');
    100        }
    101      })()
    102    `);
    103    const {data} = await response;
    104    assert_equals(data === "success", loaded);
    105  }, `A ServiceWorker with ${worker_coep} use CacheStorage to get a ${response_corp} response.`)
    106 }
    107 
    108 // ------------------------------------------------------
    109 //    worker_coep         , response_corp       , loaded
    110 // ------------------------------------------------------
    111 check("coep-none"         , "corp-undefined"    , true);
    112 check("coep-none"         , "corp-cross-origin" , true);
    113 check("coep-require-corp" , "corp-undefined"    , false);
    114 check("coep-require-corp" , "corp-cross-origin" , true);
    115 
    116 </script>
    117 </html>