tor-browser

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

browser_etp_permission.js (5386B)


      1 "use strict";
      2 
      3 const { PermissionTestUtils } = ChromeUtils.importESModule(
      4  "resource://testing-common/PermissionTestUtils.sys.mjs"
      5 );
      6 
      7 const BASE_URI = "http://mochi.test:8888/browser/dom/serviceworkers/test/";
      8 const PAGE_URI = BASE_URI + "empty.html";
      9 const SCOPE = PAGE_URI + "?etp_permission";
     10 const SW_SCRIPT = BASE_URI + "service_worker_etp.js";
     11 
     12 // Test that a service worker respects ETP permissions
     13 // during ServiceWorkerPrivate::Initialize.
     14 add_task(async function test_permission_during_init() {
     15  await SpecialPowers.pushPrefEnv({
     16    set: [
     17      ["privacy.fingerprintingProtection", true],
     18      [
     19        "privacy.fingerprintingProtection.overrides",
     20        "+CanvasImageExtractionPrompt",
     21      ],
     22    ],
     23  });
     24 
     25  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
     26  await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
     27 
     28  const checkAllowList = async expected => {
     29    await SpecialPowers.spawn(
     30      tab.linkedBrowser,
     31      [{ script: SW_SCRIPT, scope: SCOPE, expected }],
     32      async function (opts) {
     33        const reg = await content.navigator.serviceWorker.register(
     34          opts.script,
     35          {
     36            scope: opts.scope,
     37          }
     38        );
     39        const worker = reg.installing || reg.waiting || reg.active;
     40        await new Promise(resolve => {
     41          if (worker.state === "activated") {
     42            resolve();
     43            return;
     44          }
     45          worker.addEventListener("statechange", function onStateChange() {
     46            if (worker.state === "activated") {
     47              worker.removeEventListener("statechange", onStateChange);
     48              resolve();
     49            }
     50          });
     51        });
     52 
     53        worker.postMessage("IsETPAllowListed");
     54        const response = await new Promise(resolve => {
     55          content.navigator.serviceWorker.onmessage = function (e) {
     56            resolve(e.data);
     57          };
     58        });
     59 
     60        is(
     61          response,
     62          opts.expected,
     63          `Service worker should ${!opts.expected ? "not" : ""} be allow-listed`
     64        );
     65 
     66        await reg.unregister();
     67      }
     68    );
     69  };
     70 
     71  await checkAllowList(false);
     72 
     73  PermissionTestUtils.add(
     74    SCOPE,
     75    "trackingprotection",
     76    Services.perms.ALLOW_ACTION
     77  );
     78 
     79  await checkAllowList(true);
     80 
     81  PermissionTestUtils.remove(SCOPE, "trackingprotection");
     82 
     83  BrowserTestUtils.removeTab(tab);
     84  await SpecialPowers.popPrefEnv();
     85 });
     86 
     87 // Test that a service worker respects ETP permissions
     88 // during service worker runtime.
     89 add_task(async function test_permission_during_runtime() {
     90  await SpecialPowers.pushPrefEnv({
     91    set: [
     92      ["privacy.fingerprintingProtection", true],
     93      [
     94        "privacy.fingerprintingProtection.overrides",
     95        "+CanvasImageExtractionPrompt",
     96      ],
     97    ],
     98  });
     99 
    100  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
    101  await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
    102 
    103  // Define functions with nice names for easier understanding
    104  const registerServiceWorker = async () => {
    105    await SpecialPowers.spawn(
    106      tab.linkedBrowser,
    107      [{ script: SW_SCRIPT, scope: SCOPE }],
    108      async function (opts) {
    109        const reg = await content.navigator.serviceWorker.register(
    110          opts.script,
    111          {
    112            scope: opts.scope,
    113          }
    114        );
    115        const worker = reg.installing || reg.waiting || reg.active;
    116        await new Promise(resolve => {
    117          if (worker.state === "activated") {
    118            resolve();
    119            return;
    120          }
    121          worker.addEventListener("statechange", function onStateChange() {
    122            if (worker.state === "activated") {
    123              worker.removeEventListener("statechange", onStateChange);
    124              resolve();
    125            }
    126          });
    127        });
    128      }
    129    );
    130  };
    131 
    132  const checkAllowList = async expected => {
    133    await SpecialPowers.spawn(
    134      tab.linkedBrowser,
    135      [{ expected }],
    136      async function (opts) {
    137        content.navigator.serviceWorker.ready.then(registration => {
    138          registration.active.postMessage("IsETPAllowListed");
    139        });
    140 
    141        const response = await new Promise(resolve => {
    142          content.navigator.serviceWorker.onmessage = function (e) {
    143            resolve(e.data);
    144          };
    145        });
    146 
    147        is(
    148          response,
    149          opts.expected,
    150          `Service worker should ${!opts.expected ? "not" : ""} be allow-listed`
    151        );
    152      }
    153    );
    154  };
    155 
    156  const unregisterServiceWorker = async () => {
    157    await SpecialPowers.spawn(
    158      tab.linkedBrowser,
    159      [{ scope: SCOPE }],
    160      async function (opts) {
    161        const registrations =
    162          await content.navigator.serviceWorker.getRegistrations();
    163        for (const registration of registrations) {
    164          if (registration.scope === opts.scope) {
    165            await registration.unregister();
    166          }
    167        }
    168      }
    169    );
    170  };
    171 
    172  // Run the actual test
    173  await registerServiceWorker();
    174 
    175  await checkAllowList(false);
    176 
    177  PermissionTestUtils.add(
    178    SCOPE,
    179    "trackingprotection",
    180    Services.perms.ALLOW_ACTION
    181  );
    182 
    183  await checkAllowList(true);
    184 
    185  PermissionTestUtils.add(
    186    SCOPE,
    187    "trackingprotection",
    188    Services.perms.DENY_ACTION
    189  );
    190 
    191  await checkAllowList(false);
    192 
    193  await unregisterServiceWorker();
    194 
    195  PermissionTestUtils.remove(SCOPE, "trackingprotection");
    196 
    197  BrowserTestUtils.removeTab(tab);
    198  await SpecialPowers.popPrefEnv();
    199 });