tor-browser

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

browser_webauthn_cert_override.js (5481B)


      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 file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 let expectSecurityError = expectError("Security");
      8 
      9 async function test_webauthn_with_cert_override({
     10  aTestDomain,
     11  aExpectSecurityError = false,
     12  aFeltPrivacyV1 = false,
     13  aAllowCertificateOverrideByPref = false,
     14 }) {
     15  let authenticatorId = add_virtual_authenticator(/*autoremove*/ false);
     16 
     17  let certOverrideService = Cc[
     18    "@mozilla.org/security/certoverride;1"
     19  ].getService(Ci.nsICertOverrideService);
     20  Services.prefs.setBoolPref(
     21    "security.certerrors.felt-privacy-v1",
     22    aFeltPrivacyV1
     23  );
     24  Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true);
     25  Services.prefs.setBoolPref(
     26    "security.webauthn.allow_with_certificate_override",
     27    aAllowCertificateOverrideByPref
     28  );
     29  let testURL = "https://" + aTestDomain;
     30  let certErrorLoaded;
     31  let tab = await BrowserTestUtils.openNewForegroundTab(
     32    gBrowser,
     33    () => {
     34      gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, testURL);
     35      let browser = gBrowser.selectedBrowser;
     36      certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
     37    },
     38    false
     39  );
     40  info("Waiting for cert error page.");
     41  await certErrorLoaded;
     42 
     43  let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
     44 
     45  info("Adding certificate error override.");
     46  await SpecialPowers.spawn(
     47    tab.linkedBrowser,
     48    [aFeltPrivacyV1],
     49    async function (aFeltPrivacyV1) {
     50      const doc = content.document;
     51 
     52      if (!aFeltPrivacyV1) {
     53        info("Using old cert error page flow.");
     54        let doc = content.document;
     55        let exceptionButton = doc.getElementById("exceptionDialogButton");
     56        exceptionButton.click();
     57      } else {
     58        info("Using felt-privacy-v1 cert error page flow.");
     59        const netErrorCard =
     60          doc.querySelector("net-error-card").wrappedJSObject;
     61        await netErrorCard.getUpdateComplete();
     62        await EventUtils.synthesizeMouseAtCenter(
     63          netErrorCard.advancedButton,
     64          {},
     65          content
     66        );
     67        await ContentTaskUtils.waitForCondition(() => {
     68          return (
     69            netErrorCard.exceptionButton &&
     70            !netErrorCard.exceptionButton.disabled
     71          );
     72        }, "Waiting for exception button");
     73        netErrorCard.exceptionButton.scrollIntoView();
     74        EventUtils.synthesizeMouseAtCenter(
     75          netErrorCard.exceptionButton,
     76          {},
     77          content
     78        );
     79      }
     80    }
     81  );
     82 
     83  info("Waiting for page load.");
     84  await loaded;
     85 
     86  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
     87    let doc = content.document;
     88    ok(
     89      !doc.documentURI.startsWith("about:certerror"),
     90      "Exception has been added."
     91    );
     92  });
     93 
     94  let makeCredPromise = promiseWebAuthnMakeCredential(tab, "none", "preferred");
     95  if (aExpectSecurityError) {
     96    await makeCredPromise.then(arrivingHereIsBad).catch(expectSecurityError);
     97    ok(
     98      true,
     99      "Calling navigator.credentials.create() results in a security error"
    100    );
    101  } else {
    102    await makeCredPromise.catch(arrivingHereIsBad);
    103    ok(true, "Calling navigator.credentials.create() is allowed");
    104  }
    105 
    106  let getAssertionPromise = promiseWebAuthnGetAssertionDiscoverable(tab);
    107  if (aExpectSecurityError) {
    108    await getAssertionPromise
    109      .then(arrivingHereIsBad)
    110      .catch(expectSecurityError);
    111    ok(true, "Calling navigator.credentials.get() results in a security error");
    112  } else {
    113    await getAssertionPromise.catch(arrivingHereIsBad);
    114    ok(true, "Calling navigator.credentials.get() results in a security error");
    115  }
    116 
    117  certOverrideService.clearValidityOverride(aTestDomain, -1, {});
    118 
    119  loaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser);
    120  BrowserCommands.reloadSkipCache();
    121  await loaded;
    122 
    123  BrowserTestUtils.removeTab(gBrowser.selectedTab);
    124 
    125  remove_virtual_authenticator(authenticatorId);
    126 
    127  Services.prefs.clearUserPref(
    128    "security.webauthn.allow_with_certificate_override"
    129  );
    130  Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost");
    131  Services.prefs.clearUserPref("security.certerrors.felt-privacy-v1");
    132 }
    133 
    134 for (let feltPrivacyV1 of [false, true]) {
    135  add_task(() =>
    136    test_webauthn_with_cert_override({
    137      aTestDomain: "expired.example.com",
    138      aExpectSecurityError: false,
    139      aFeltPrivacyV1: feltPrivacyV1,
    140      aAllowCertificateOverrideByPref: false,
    141    })
    142  );
    143  add_task(() =>
    144    test_webauthn_with_cert_override({
    145      aTestDomain: "untrusted.example.com",
    146      aExpectSecurityError: true,
    147      aFeltPrivacyV1: feltPrivacyV1,
    148      aAllowCertificateOverrideByPref: false,
    149    })
    150  );
    151  add_task(() =>
    152    test_webauthn_with_cert_override({
    153      aTestDomain: "no-subject-alt-name.example.com",
    154      aExpectSecurityError: true,
    155      aFeltPrivacyV1: feltPrivacyV1,
    156      aAllowCertificateOverrideByPref: false,
    157    })
    158  );
    159  add_task(() =>
    160    test_webauthn_with_cert_override({
    161      aTestDomain: "badcertdomain.localhost",
    162      aExpectSecurityError: false,
    163      aFeltPrivacyV1: feltPrivacyV1,
    164      aAllowCertificateOverrideByPref: false,
    165    })
    166  );
    167  add_task(() =>
    168    test_webauthn_with_cert_override({
    169      aTestDomain: "untrusted.example.com",
    170      aExpectSecurityError: false,
    171      aFeltPrivacyV1: feltPrivacyV1,
    172      aAllowCertificateOverrideByPref: true,
    173    })
    174  );
    175 }