tor-browser

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

browser_storage_dfpi.js (5791B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // Basic test to assert that the storage tree and table corresponding to each
      6 // item in the storage tree is correctly displayed
      7 
      8 "use strict";
      9 
     10 const { SiteDataTestUtils } = ChromeUtils.importESModule(
     11  "resource://testing-common/SiteDataTestUtils.sys.mjs"
     12 );
     13 
     14 // Ensure iframe.src in storage-dfpi.html starts with PREFIX.
     15 const PREFIX = "https://sub1.test1.example";
     16 const ORIGIN = `${PREFIX}.org`;
     17 const ORIGIN_THIRD_PARTY = `${PREFIX}.com`;
     18 const ORIGIN_PARTITIONED = `${PREFIX}.com^partitionKey=%28https%2Cexample.org%29`;
     19 const TEST_URL = `${ORIGIN}/document-builder.sjs?html=
     20    <iframe src="${PREFIX}.com/browser/devtools/client/storage/test/storage-blank.html"></iframe>
     21 `;
     22 
     23 function listOrigins() {
     24  return new Promise(resolve => {
     25    SpecialPowers.Services.qms.listOrigins().callback = req => {
     26      resolve(req.result);
     27    };
     28  });
     29 }
     30 
     31 add_task(async function () {
     32  await pushPref(
     33    "network.cookie.cookieBehavior",
     34    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
     35  );
     36 
     37  registerCleanupFunction(SiteDataTestUtils.clear);
     38 
     39  const expectedOrigins = [ORIGIN, ORIGIN_PARTITIONED];
     40 
     41  // `Services.qms.listOrigins()` may or contain results created by other tests.
     42  // And it's unsafe to clear existing origins by `Services.qms.clear()`.
     43  // In order to obtain correct results, we need to compare the results before
     44  // and after `openTabAndSetupStorage` is called.
     45  // To ensure more accurate results, try choosing a uncommon origin for PREFIX.
     46  const EXISTING_ORIGINS = await listOrigins();
     47  expectedOrigins.forEach(expected => {
     48    ok(!EXISTING_ORIGINS.includes(expected), `${expected} doesn't exist`);
     49  });
     50 
     51  await openTabAndSetupStorage(TEST_URL);
     52 
     53  const origins = await listOrigins();
     54  for (const origin of origins) {
     55    ok(
     56      EXISTING_ORIGINS.includes(origin) || expectedOrigins.includes(origin),
     57      `check origin: ${origin}`
     58    );
     59  }
     60  expectedOrigins.forEach(expected => {
     61    ok(origins.includes(expected), `${expected} is added`);
     62  });
     63 
     64  BrowserTestUtils.removeTab(gBrowser.selectedTab);
     65 });
     66 
     67 async function setPartitionedStorage(browser, type, key) {
     68  const handler = async (storageType, storageKey, storageValue) => {
     69    if (storageType == "cookie") {
     70      content.document.cookie = `${storageKey}=${storageValue}`;
     71      return;
     72    }
     73    content.localStorage.setItem(storageKey, storageValue);
     74  };
     75 
     76  const thirdPartyHandler = async (storageType, storageKey, storageValue) => {
     77    if (storageType == "cookie") {
     78      content.document.cookie = `${storageKey}=${storageValue}; SameSite=None; Secure; Partitioned;`;
     79      return;
     80    }
     81    content.localStorage.setItem(storageKey, storageValue);
     82  };
     83 
     84  // Set first party storage.
     85  await SpecialPowers.spawn(browser, [type, key, "first"], handler);
     86  // Set third-party (partitioned) storage in the iframe.
     87  await SpecialPowers.spawn(
     88    browser.browsingContext.children[0],
     89    [type, key, "third"],
     90    thirdPartyHandler
     91  );
     92 }
     93 
     94 async function checkData(storageType, key, value) {
     95  if (storageType == "cookie") {
     96    checkCookieData(key, value);
     97    return;
     98  }
     99  await waitForStorageData(key, value);
    100 }
    101 
    102 async function testPartitionedStorage(
    103  storageType,
    104  treeItemLabel = storageType
    105 ) {
    106  await pushPref(
    107    "network.cookie.cookieBehavior",
    108    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
    109  );
    110  // Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default"
    111  await pushPref("network.cookie.sameSite.laxByDefault", false);
    112 
    113  info(
    114    "Open the test url in a new tab and add storage entries *before* opening the storage panel."
    115  );
    116  await BrowserTestUtils.withNewTab(TEST_URL, async browser => {
    117    await setPartitionedStorage(browser, storageType, "contextA");
    118  });
    119 
    120  await openTabAndSetupStorage(TEST_URL);
    121 
    122  const doc = gPanelWindow.document;
    123 
    124  info("check that both hosts appear in the storage tree");
    125  checkTree(doc, [treeItemLabel, ORIGIN]);
    126  checkTree(doc, [treeItemLabel, ORIGIN_THIRD_PARTY]);
    127 
    128  info(
    129    "check that items for both first and third party host have the initial storage entries"
    130  );
    131 
    132  await selectTreeItem([treeItemLabel, ORIGIN]);
    133  await checkData(storageType, "contextA", "first");
    134 
    135  await selectTreeItem([treeItemLabel, ORIGIN_THIRD_PARTY]);
    136  await checkData(storageType, "contextA", "third");
    137 
    138  info("Add more entries while the storage panel is open");
    139  const onUpdated = gUI.once("store-objects-edit");
    140  await setPartitionedStorage(
    141    gBrowser.selectedBrowser,
    142    storageType,
    143    "contextB"
    144  );
    145  await onUpdated;
    146 
    147  info("check that both hosts appear in the storage tree");
    148  checkTree(doc, [treeItemLabel, ORIGIN]);
    149  checkTree(doc, [treeItemLabel, ORIGIN_THIRD_PARTY]);
    150 
    151  info(
    152    "check that items for both first and third party host have the updated storage entries"
    153  );
    154 
    155  await selectTreeItem([treeItemLabel, ORIGIN]);
    156  await checkData(storageType, "contextA", "first");
    157  await checkData(storageType, "contextB", "first");
    158 
    159  await selectTreeItem([treeItemLabel, ORIGIN_THIRD_PARTY]);
    160  await checkData(storageType, "contextA", "third");
    161  await checkData(storageType, "contextB", "third");
    162 
    163  BrowserTestUtils.removeTab(gBrowser.selectedTab);
    164 }
    165 
    166 // Tests that partitioned storage is shown in the storage panel.
    167 
    168 add_task(async function test_partitioned_cookies() {
    169  registerCleanupFunction(SiteDataTestUtils.clear);
    170  await testPartitionedStorage("cookie", "cookies");
    171 });
    172 
    173 add_task(async function test_partitioned_localStorage() {
    174  registerCleanupFunction(SiteDataTestUtils.clear);
    175  await testPartitionedStorage("localStorage");
    176 });