summaryrefslogtreecommitdiffstats
path: root/dom/security/test/https-only/browser_websocket_exceptions.js
blob: f68a834ceee8e6a420a1a3e3b5aea24a33f6df5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"use strict";

const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "http://localhost:9898"
);

let WEBSOCKET_DOC_URL = `${TEST_PATH_HTTP}file_websocket_exceptions.html`;

add_task(async function () {
  // Here is a sequence of how this test works:
  // 1. Dynamically inject a localhost iframe
  // 2. Add an exemption for localhost
  // 3. Fire up Websocket
  // Generally local IP addresses are exempt from https-only, but if we do not add
  // an exemption for localhost, then the TriggeringPrincipal of the WebSocket is
  // `not` exempt and we would upgrade ws to wss.

  await SpecialPowers.pushPrefEnv({
    set: [
      ["dom.security.https_only_mode", true],
      ["network.proxy.allow_hijacking_localhost", true],
    ],
  });

  await BrowserTestUtils.withNewTab("about:blank", async function (browser) {
    let loaded = BrowserTestUtils.browserLoaded(browser);

    BrowserTestUtils.loadURIString(browser, WEBSOCKET_DOC_URL);
    await loaded;

    await SpecialPowers.spawn(browser, [], async function () {
      // Part 1:
      let myIframe = content.document.createElement("iframe");
      content.document.body.appendChild(myIframe);
      myIframe.src =
        "http://localhost:9898/browser/dom/security/test/https-only/file_websocket_exceptions_iframe.html";

      myIframe.onload = async function () {
        // Part 2:
        await SpecialPowers.pushPermissions([
          {
            type: "https-only-load-insecure",
            allow: true,
            context: "http://localhost:9898",
          },
        ]);
        // Part 3.
        myIframe.contentWindow.postMessage({ myMessage: "runWebSocket" }, "*");
      };

      const promise = new Promise(resolve => {
        content.addEventListener("WebSocketEnded", resolve, {
          once: true,
        });
      });

      const { detail } = await promise;

      is(detail.state, "onopen", "sanity: websocket loaded");
      ok(
        detail.url.startsWith("ws://example.com/tests"),
        "exempt websocket should not be upgraded to wss://"
      );
    });
  });
  await SpecialPowers.popPermissions();
});