tor-browser

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

browser_webconsole_trackingprotection_errors.js (11717B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 // Load a page with tracking elements that get blocked and make sure that a
      5 // 'learn more' link shows up in the webconsole.
      6 
      7 "use strict";
      8 requestLongerTimeout(2);
      9 
     10 const TEST_PATH = "browser/devtools/client/webconsole/test/browser/";
     11 const TEST_FILE = TEST_PATH + "test-trackingprotection-securityerrors.html";
     12 const TEST_FILE_THIRD_PARTY_ONLY =
     13  TEST_PATH + "test-trackingprotection-securityerrors-thirdpartyonly.html";
     14 const TEST_URI = "https://example.com/" + TEST_FILE;
     15 const TEST_URI_THIRD_PARTY_ONLY =
     16  "https://example.com/" + TEST_FILE_THIRD_PARTY_ONLY;
     17 const TRACKER_URL = "https://tracking.example.org/";
     18 const THIRD_PARTY_URL = "https://example.org/";
     19 const BLOCKED_URL = `\u201c${
     20  TRACKER_URL + TEST_PATH + "cookieSetter.html"
     21 }\u201d`;
     22 const PARTITIONED_URL = `\u201c${
     23  THIRD_PARTY_URL + TEST_PATH
     24 }cookieSetter.html\u201d`;
     25 
     26 const COOKIE_BEHAVIOR_PREF = "network.cookie.cookieBehavior";
     27 const COOKIE_BEHAVIORS = {
     28  // reject all third-party cookies
     29  REJECT_FOREIGN: 1,
     30  // reject all cookies
     31  REJECT: 2,
     32  // reject third-party cookies unless the eTLD already has at least one cookie
     33  LIMIT_FOREIGN: 3,
     34  // reject trackers
     35  REJECT_TRACKER: 4,
     36  // dFPI - partitioned access to third-party cookies
     37  PARTITION_FOREIGN: 5,
     38 };
     39 
     40 const { UrlClassifierTestUtils } = ChromeUtils.importESModule(
     41  "resource://testing-common/UrlClassifierTestUtils.sys.mjs"
     42 );
     43 
     44 registerCleanupFunction(async function () {
     45  UrlClassifierTestUtils.cleanupTestTrackers();
     46 
     47  await new Promise(resolve => {
     48    Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
     49      resolve()
     50    );
     51  });
     52 });
     53 
     54 pushPref("devtools.webconsole.groupSimilarMessages", false);
     55 
     56 add_task(async function testEnhancedTrackingProtectionMessage() {
     57  await UrlClassifierTestUtils.addTestTrackers();
     58 
     59  await pushPref("privacy.trackingprotection.enabled", true);
     60  const hud = await openNewTabAndConsole(TRACKER_URL + TEST_FILE);
     61 
     62  info("Test tracking protection message");
     63  const message = await waitFor(() =>
     64    findWarningMessage(
     65      hud,
     66      `The resource at \u201chttps://tracking.example.com/\u201d was blocked because ` +
     67        `Enhanced Tracking Protection is enabled`
     68    )
     69  );
     70 
     71  await testLearnMoreClickOpenNewTab(
     72    message,
     73    "https://developer.mozilla.org/Web/Privacy/Guides/Firefox_tracking_protection" +
     74      DOCS_GA_PARAMS
     75  );
     76 });
     77 
     78 add_task(async function testForeignCookieBlockedMessage() {
     79  info("Test foreign cookie blocked message");
     80  // Bug 1518138: GC heuristics are broken for this test, so that the test
     81  // ends up running out of memory. Try to work-around the problem by GCing
     82  // before the test begins.
     83  Cu.forceShrinkingGC();
     84  // We change the pref and open a new window to ensure it will be taken into account.
     85  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_FOREIGN);
     86  const { hud, win } = await openNewWindowAndConsole(TEST_URI);
     87  const message = await waitFor(() =>
     88    findWarningMessage(
     89      hud,
     90      `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` +
     91        `blocking all third-party storage access requests and Enhanced Tracking Protection is enabled`
     92    )
     93  );
     94  await testLearnMoreClickOpenNewTab(
     95    message,
     96    getStorageErrorUrl("CookieBlockedForeign")
     97  );
     98  // We explicitly destroy the toolbox in order to ensure waiting for its full destruction
     99  // and avoid leak / pending requests
    100  await hud.toolbox.destroy();
    101  win.close();
    102 });
    103 
    104 add_task(async function testLimitForeignCookieBlockedMessage() {
    105  info("Test unvisited eTLD foreign cookies blocked message");
    106  // Bug 1518138: GC heuristics are broken for this test, so that the test
    107  // ends up running out of memory. Try to work-around the problem by GCing
    108  // before the test begins.
    109  Cu.forceShrinkingGC();
    110  // We change the pref and open a new window to ensure it will be taken into account.
    111  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.LIMIT_FOREIGN);
    112  const { hud, win } = await openNewWindowAndConsole(TEST_URI);
    113 
    114  const message = await waitFor(
    115    () =>
    116      findWarningMessage(
    117        hud,
    118        `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` +
    119          `blocking all third-party storage access requests and Enhanced Tracking Protection is enabled`
    120      ),
    121    "Wait for 'blocking all third-party storage access' message",
    122    100
    123  );
    124  ok(true, "Third-party storage access blocked message was displayed");
    125 
    126  info("Check that clicking on the Learn More link works as expected");
    127  await testLearnMoreClickOpenNewTab(
    128    message,
    129    getStorageErrorUrl("CookieBlockedForeign")
    130  );
    131  // We explicitely destroy the toolbox in order to ensure waiting for its full destruction
    132  // and avoid leak / pending requests
    133  await hud.toolbox.destroy();
    134  win.close();
    135 });
    136 
    137 add_task(async function testAllCookieBlockedMessage() {
    138  info("Test all cookies blocked message");
    139  // We change the pref and open a new window to ensure it will be taken into account.
    140  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT);
    141  const { hud, win } = await openNewWindowAndConsole(TEST_URI);
    142 
    143  const message = await waitFor(() =>
    144    findWarningMessage(
    145      hud,
    146      `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` +
    147        `blocking all storage access requests`
    148    )
    149  );
    150  await testLearnMoreClickOpenNewTab(
    151    message,
    152    getStorageErrorUrl("CookieBlockedAll")
    153  );
    154  // We explicitely destroy the toolbox in order to ensure waiting for its full destruction
    155  // and avoid leak / pending requests
    156  await hud.toolbox.destroy();
    157  win.close();
    158 });
    159 
    160 add_task(async function testTrackerCookieBlockedMessage() {
    161  info("Test tracker cookie blocked message");
    162  // We change the pref and open a new window to ensure it will be taken into account.
    163  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_TRACKER);
    164  const { hud, win } = await openNewWindowAndConsole(TEST_URI);
    165 
    166  const message = await waitFor(() =>
    167    findWarningMessage(
    168      hud,
    169      `Request to access cookie or storage on ${BLOCKED_URL} was blocked because it came ` +
    170        `from a tracker and Enhanced Tracking Protection is enabled`
    171    )
    172  );
    173  await testLearnMoreClickOpenNewTab(
    174    message,
    175    getStorageErrorUrl("CookieBlockedTracker")
    176  );
    177  // We explicitely destroy the toolbox in order to ensure waiting for its full destruction
    178  // and avoid leak / pending requests
    179  await hud.toolbox.destroy();
    180  win.close();
    181 });
    182 
    183 add_task(async function testForeignCookiePartitionedMessage() {
    184  info("Test tracker cookie blocked message");
    185  // We change the pref and open a new window to ensure it will be taken into account.
    186  await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.PARTITION_FOREIGN);
    187  const { hud, win } = await openNewWindowAndConsole(TEST_URI_THIRD_PARTY_ONLY);
    188 
    189  const message = await waitFor(() =>
    190    findWarningMessage(
    191      hud,
    192      `Partitioned cookie or storage access was provided to ${PARTITIONED_URL} because it is ` +
    193        `loaded in the third-party context and dynamic state partitioning is enabled.`
    194    )
    195  );
    196  await testLearnMoreClickOpenNewTab(
    197    message,
    198    getStorageErrorUrl("CookiePartitionedForeign")
    199  );
    200  // We explicitely destroy the toolbox in order to ensure waiting for its full destruction
    201  // and avoid leak / pending requests
    202  await hud.toolbox.destroy();
    203  win.close();
    204 });
    205 
    206 add_task(async function testCookieBlockedByPermissionMessage() {
    207  info("Test cookie blocked by permission message");
    208  // Turn off tracking protection and add a block permission on the URL.
    209  await pushPref("privacy.trackingprotection.enabled", false);
    210  const p =
    211    Services.scriptSecurityManager.createContentPrincipalFromOrigin(
    212      TRACKER_URL
    213    );
    214  Services.perms.addFromPrincipal(
    215    p,
    216    "cookie",
    217    Ci.nsIPermissionManager.DENY_ACTION
    218  );
    219 
    220  const { hud, win } = await openNewWindowAndConsole(TEST_URI);
    221  const message = await waitFor(() =>
    222    findWarningMessage(
    223      hud,
    224      `Request to access cookies or ` +
    225        `storage on ${BLOCKED_URL} was blocked because of custom cookie permission`
    226    )
    227  );
    228  await testLearnMoreClickOpenNewTab(
    229    message,
    230    getStorageErrorUrl("CookieBlockedByPermission")
    231  );
    232  // We explicitely destroy the toolbox in order to ensure waiting for its full destruction
    233  // and avoid leak / pending requests
    234  await hud.toolbox.destroy();
    235  win.close();
    236 
    237  // Remove the custom permission.
    238  Services.perms.removeFromPrincipal(p, "cookie");
    239 });
    240 
    241 add_task(async function testCookieBlockedForUserContentResourceMessage() {
    242  info("Test usercontent resource cookie blocking");
    243  // Bug 1518138: GC heuristics are broken for this test, so that the test
    244  // ends up running out of memory. Try to work-around the problem by GCing
    245  // before the test begins.
    246  Cu.forceShrinkingGC();
    247  await pushPref("privacy.antitracking.isolateContentScriptResources", true);
    248 
    249  const extension = ExtensionTestUtils.loadExtension({
    250    manifest: {
    251      content_scripts: [
    252        {
    253          matches: [`*://example.com/*/test-blank.html`],
    254          js: ["content_scripts.js"],
    255          all_frames: true,
    256        },
    257      ],
    258    },
    259    files: {
    260      "content_scripts.js": `
    261            // An image
    262            const img = document.createElement("img");
    263            img.src = "https://example.com/${TEST_PATH}test-image.png";
    264            document.body.appendChild(img);
    265 
    266            // A script
    267            const script = document.createElement("script");
    268            script.src = "https://example.com/${TEST_PATH}empty-with-cookie.js";
    269            document.body.appendChild(script);
    270          `,
    271    },
    272  });
    273 
    274  await extension.startup();
    275 
    276  const { hud, win } = await openNewWindowAndConsole(
    277    "https://example.com/" + TEST_PATH + "test-blank.html"
    278  );
    279 
    280  await waitFor(
    281    () =>
    282      findWarningMessage(
    283        hud,
    284        "Request to access cookie or storage on “https://example.com/" +
    285          `${TEST_PATH}test-image.png” was blocked because we are blocking all ` +
    286          "storage access requests."
    287      ) &&
    288      findWarningMessage(
    289        hud,
    290        "Request to access cookie or storage on “https://example.com/" +
    291          `${TEST_PATH}empty-with-cookie.js” was blocked because we are ` +
    292          "blocking all storage access requests."
    293      )
    294  );
    295  ok(true, "Third-party storage access blocked message was displayed");
    296 
    297  // We explicitly destroy the toolbox in order to ensure waiting for its full destruction
    298  // and avoid leak / pending requests
    299  await hud.toolbox.destroy();
    300  win.close();
    301 
    302  await extension.unload();
    303 });
    304 
    305 function getStorageErrorUrl(category) {
    306  const BASE_STORAGE_ERROR_URL =
    307    "https://developer.mozilla.org/docs/Web/Privacy/Guides/Storage_Access_Policy/Errors/";
    308  const STORAGE_ERROR_URL_PARAMS = new URLSearchParams({
    309    utm_source: "devtools",
    310    utm_medium: "firefox-cookie-errors",
    311    utm_campaign: "default",
    312  }).toString();
    313  return `${BASE_STORAGE_ERROR_URL}${category}?${STORAGE_ERROR_URL_PARAMS}`;
    314 }
    315 
    316 async function testLearnMoreClickOpenNewTab(message, expectedUrl) {
    317  info("Clicking on the Learn More link");
    318 
    319  const learnMoreLink = message.querySelector(".learn-more-link");
    320  const linkSimulation = await simulateLinkClick(learnMoreLink);
    321  checkLink({
    322    ...linkSimulation,
    323    expectedLink: expectedUrl,
    324    expectedTab: "tab",
    325  });
    326 }
    327 
    328 function checkLink({ link, where, expectedLink, expectedTab }) {
    329  is(link, expectedLink, `Clicking the provided link opens ${link}`);
    330  is(where, expectedTab, `Clicking the provided link opens in expected tab`);
    331 }