tor-browser

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

browser_aboutCertError_mitm.js (5158B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const PREF_MITM_PRIMING = "security.certerrors.mitm.priming.enabled";
      7 const PREF_MITM_PRIMING_ENDPOINT = "security.certerrors.mitm.priming.endpoint";
      8 const PREF_MITM_CANARY_ISSUER = "security.pki.mitm_canary_issuer";
      9 const PREF_MITM_AUTO_ENABLE_ENTERPRISE_ROOTS =
     10  "security.certerrors.mitm.auto_enable_enterprise_roots";
     11 const PREF_ENTERPRISE_ROOTS = "security.enterprise_roots.enabled";
     12 const PREF_FELT_PRIV_V1 = "security.certerrors.felt-privacy-v1";
     13 
     14 const UNKNOWN_ISSUER = "https://untrusted.example.com";
     15 
     16 async function checkMitmPriming(useFelt) {
     17  await SpecialPowers.pushPrefEnv({
     18    set: [
     19      [PREF_MITM_PRIMING, true],
     20      [PREF_MITM_PRIMING_ENDPOINT, UNKNOWN_ISSUER],
     21      [PREF_ENTERPRISE_ROOTS, false],
     22      [PREF_FELT_PRIV_V1, useFelt],
     23    ],
     24  });
     25 
     26  let browser;
     27  let certErrorLoaded;
     28  await BrowserTestUtils.openNewForegroundTab(
     29    gBrowser,
     30    () => {
     31      gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, UNKNOWN_ISSUER);
     32      browser = gBrowser.selectedBrowser;
     33      // The page will reload by itself after the initial canary request, so we wait
     34      // until the AboutNetErrorLoad event has happened twice.
     35      certErrorLoaded = new Promise(resolve => {
     36        let loaded = 0;
     37        let removeEventListener = BrowserTestUtils.addContentEventListener(
     38          browser,
     39          "AboutNetErrorLoad",
     40          () => {
     41            if (++loaded == 2) {
     42              removeEventListener();
     43              resolve();
     44            }
     45          },
     46          { capture: false, wantUntrusted: true }
     47        );
     48      });
     49    },
     50    false
     51  );
     52 
     53  await certErrorLoaded;
     54 
     55  await SpecialPowers.spawn(browser, [], () => {
     56    is(
     57      content.document.body.getAttribute("code"),
     58      "MOZILLA_PKIX_ERROR_MITM_DETECTED",
     59      "MitM error page has loaded."
     60    );
     61  });
     62 
     63  ok(true, "Successfully loaded the MitM error page.");
     64 
     65  is(
     66    Services.prefs.getStringPref(PREF_MITM_CANARY_ISSUER),
     67    "CN=Unknown CA",
     68    "Stored the correct issuer"
     69  );
     70 
     71  await SpecialPowers.spawn(browser, [], async () => {
     72    const shortDesc = content.document.querySelector("#errorShortDesc");
     73    const whatToDo = content.document.querySelector("#errorWhatToDoText");
     74 
     75    await ContentTaskUtils.waitForCondition(
     76      () => shortDesc.textContent != "" && whatToDo.textContent != "",
     77      "DOM localization has been updated"
     78    );
     79 
     80    ok(
     81      shortDesc.textContent.includes("Unknown CA"),
     82      "Shows the name of the issuer."
     83    );
     84 
     85    ok(
     86      whatToDo.textContent.includes("Unknown CA"),
     87      "Shows the name of the issuer."
     88    );
     89  });
     90 
     91  BrowserTestUtils.removeTab(gBrowser.selectedTab);
     92  await SpecialPowers.clearUserPref(PREF_MITM_CANARY_ISSUER);
     93  await SpecialPowers.flushPrefEnv();
     94 }
     95 
     96 async function checkMitmAutoEnableEnterpriseRoots(useFelt) {
     97  await SpecialPowers.pushPrefEnv({
     98    set: [
     99      [PREF_MITM_PRIMING, true],
    100      [PREF_MITM_PRIMING_ENDPOINT, UNKNOWN_ISSUER],
    101      [PREF_MITM_AUTO_ENABLE_ENTERPRISE_ROOTS, true],
    102      [PREF_ENTERPRISE_ROOTS, false],
    103      [PREF_FELT_PRIV_V1, !!useFelt],
    104    ],
    105  });
    106 
    107  let browser;
    108  let certErrorLoaded;
    109 
    110  let prefChanged = TestUtils.waitForPrefChange(
    111    PREF_ENTERPRISE_ROOTS,
    112    value => value === true
    113  );
    114  await BrowserTestUtils.openNewForegroundTab(
    115    gBrowser,
    116    () => {
    117      gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, UNKNOWN_ISSUER);
    118      browser = gBrowser.selectedBrowser;
    119      // The page will reload by itself after the initial canary request, so we wait
    120      // until the AboutNetErrorLoad event has happened twice.
    121      certErrorLoaded = new Promise(resolve => {
    122        let loaded = 0;
    123        let removeEventListener = BrowserTestUtils.addContentEventListener(
    124          browser,
    125          "AboutNetErrorLoad",
    126          () => {
    127            if (++loaded == 2) {
    128              removeEventListener();
    129              resolve();
    130            }
    131          },
    132          { capture: false, wantUntrusted: true }
    133        );
    134      });
    135    },
    136    false
    137  );
    138 
    139  await certErrorLoaded;
    140  await prefChanged;
    141 
    142  await SpecialPowers.spawn(browser, [], () => {
    143    is(
    144      content.document.body.getAttribute("code"),
    145      "MOZILLA_PKIX_ERROR_MITM_DETECTED",
    146      "MitM error page has loaded."
    147    );
    148  });
    149 
    150  ok(true, "Successfully loaded the MitM error page.");
    151 
    152  ok(
    153    !Services.prefs.prefHasUserValue(PREF_ENTERPRISE_ROOTS),
    154    "Flipped the enterprise roots pref back"
    155  );
    156 
    157  BrowserTestUtils.removeTab(gBrowser.selectedTab);
    158  await SpecialPowers.clearUserPref(PREF_MITM_CANARY_ISSUER);
    159  await SpecialPowers.flushPrefEnv();
    160 }
    161 // Check that basic MitM priming works and the MitM error page is displayed successfully.
    162 add_task(async function runCheckMitmPriming() {
    163  for (const useFelt of [true, false]) {
    164    await checkMitmPriming(useFelt);
    165  }
    166 });
    167 
    168 // Check that we set the enterprise roots pref correctly on MitM
    169 add_task(async function runCheckMitmAutoEnableEnterpriseRoots() {
    170  for (const useFelt of [true, false]) {
    171    await checkMitmAutoEnableEnterpriseRoots(useFelt);
    172  }
    173 });