tor-browser

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

browser_net_security-state.js (3762B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /**
      7 * Test that correct security state indicator appears depending on the security
      8 * state.
      9 */
     10 
     11 add_task(async function () {
     12  // This test explicitly asserts some insecure domains.
     13  await pushPref("dom.security.https_first", false);
     14 
     15  const EXPECTED_SECURITY_STATES = {
     16    "test1.example.com": "security-state-insecure",
     17    "example.com": "security-state-secure",
     18    "nocert.example.com": "security-state-broken",
     19    localhost: "security-state-secure",
     20    notlocalhost: "security-state-insecure",
     21  };
     22 
     23  const { tab, monitor } = await initNetMonitor(CUSTOM_GET_URL, {
     24    requestCount: 1,
     25  });
     26  const { document, store, windowRequire } = monitor.panelWin;
     27  const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
     28 
     29  store.dispatch(Actions.batchEnable(false));
     30 
     31  await performRequests();
     32 
     33  for (const subitemNode of Array.from(
     34    document.querySelectorAll(".requests-list-column.requests-list-domain")
     35  )) {
     36    // Skip header
     37    const icon = subitemNode.querySelector(".requests-security-state-icon");
     38    if (!icon) {
     39      continue;
     40    }
     41 
     42    const domain = subitemNode.textContent;
     43    info("Found a request to " + domain);
     44 
     45    const classes = icon.classList;
     46    const expectedClass = EXPECTED_SECURITY_STATES[domain];
     47 
     48    info("Classes of security state icon are: " + classes);
     49    info("Security state icon is expected to contain class: " + expectedClass);
     50    ok(
     51      classes.contains(expectedClass),
     52      "Icon contained the correct class name."
     53    );
     54  }
     55 
     56  return teardown(monitor);
     57 
     58  /**
     59   * A helper that performs requests to
     60   *  - https://nocert.example.com (broken)
     61   *  - https://example.com (secure)
     62   *  - http://test1.example.com (insecure)
     63   *  - http://localhost (local)
     64   * and waits until NetworkMonitor has handled all packets sent by the server.
     65   */
     66  async function performRequests() {
     67    function executeRequests(count, url) {
     68      return SpecialPowers.spawn(
     69        tab.linkedBrowser,
     70        [{ count, url }],
     71        async function (args) {
     72          content.wrappedJSObject.performRequests(args.count, args.url);
     73        }
     74      );
     75    }
     76 
     77    let done = waitForNetworkEvents(monitor, 1);
     78    info("Requesting a resource that has a certificate problem.");
     79    await executeRequests(1, "https://nocert.example.com");
     80 
     81    // Wait for the request to complete before firing another request. Otherwise
     82    // the request with security issues interfere with waitForNetworkEvents.
     83    info("Waiting for request to complete.");
     84    await done;
     85 
     86    // Next perform a request over HTTP. If done the other way around the latter
     87    // occasionally hangs waiting for event timings that don't seem to appear...
     88    done = waitForNetworkEvents(monitor, 1);
     89    info("Requesting a resource over HTTP.");
     90    await executeRequests(1, "http://test1.example.com" + CORS_SJS_PATH);
     91    await done;
     92 
     93    done = waitForNetworkEvents(monitor, 1);
     94    info("Requesting a resource over HTTPS.");
     95    await executeRequests(1, "https://example.com" + CORS_SJS_PATH);
     96    await done;
     97 
     98    done = waitForNetworkEvents(monitor, 1);
     99    info("Requesting a resource over HTTP to localhost.");
    100    await executeRequests(1, "http://localhost" + CORS_SJS_PATH);
    101    await done;
    102 
    103    done = waitForNetworkEvents(monitor, 1);
    104    info("Requesting a resource over HTTP to notlocalhost.");
    105    await executeRequests(1, "http://notlocalhost" + CORS_SJS_PATH);
    106    await done;
    107 
    108    const expectedCount = Object.keys(EXPECTED_SECURITY_STATES).length;
    109    is(
    110      store.getState().requests.requests.length,
    111      expectedCount,
    112      expectedCount + " events logged."
    113    );
    114  }
    115 });