tor-browser

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

browser_iframe_test.js (6359B)


      1 // Bug 1658264 - Https-Only: HTTPS-Only and iFrames
      2 // https://bugzilla.mozilla.org/show_bug.cgi?id=1658264
      3 "use strict";
      4 
      5 // > How does this test work?
      6 // We're sending a request to file_iframe_test.sjs with various
      7 // browser-configurations. The sjs-file returns a website with two iFrames
      8 // loading the same sjs-file again. One iFrame is same origin (example.com) and
      9 // the other cross-origin (example.org) Each request gets saved in a semicolon
     10 // seperated list of strings. The sjs-file gets initialized with the
     11 // query-string "setup" and the result string can be polled with "results". Each
     12 // string has this format: {top/com/org}-{queryString}-{scheme}. In the end
     13 // we're just checking if all expected requests were recorded and had the
     14 // correct scheme. Requests that are meant to fail should explicitly not be
     15 // contained in the list of results.
     16 
     17 // The test loads all tabs and evaluates when all have finished loading
     18 // it may take quite a long time.
     19 // This requires more twice as much as the default 45 seconds per test:
     20 requestLongerTimeout(2);
     21 SimpleTest.requestCompleteLog();
     22 
     23 add_task(async function () {
     24  await setup();
     25 
     26  // Using this variable to parallelize and collect tests
     27  let testSet = [];
     28 
     29  /*
     30   * HTTPS-Only Mode disabled
     31   */
     32  await SpecialPowers.pushPrefEnv({
     33    set: [["dom.security.https_only_mode", false]],
     34  });
     35 
     36  // Top-Level scheme: HTTP
     37  // NOTE(freddyb): Test case temporarily disabled. See bug 1735565
     38  /*testSet.push(
     39    runTest({
     40      queryString: "test1.1",
     41      topLevelScheme: "http",
     42 
     43      expectedTopLevel: "http",
     44      expectedSameOrigin: "http",
     45      expectedCrossOrigin: "http",
     46    })
     47  );*/
     48  // Top-Level scheme: HTTPS
     49  testSet.push(
     50    runTest({
     51      queryString: "test1.2",
     52      topLevelScheme: "https",
     53 
     54      expectedTopLevel: "https",
     55      expectedSameOrigin: "fail",
     56      expectedCrossOrigin: "fail",
     57    })
     58  );
     59 
     60  await Promise.all(testSet);
     61  testSet = [];
     62  /*
     63   * HTTPS-Only Mode enabled, no exception
     64   */
     65  await SpecialPowers.pushPrefEnv({
     66    set: [["dom.security.https_only_mode", true]],
     67  });
     68 
     69  // Top-Level scheme: HTTP
     70  testSet.push(
     71    runTest({
     72      queryString: "test2.1",
     73      topLevelScheme: "http",
     74 
     75      expectedTopLevel: "https",
     76      expectedSameOrigin: "https",
     77      expectedCrossOrigin: "https",
     78    })
     79  );
     80  // Top-Level scheme: HTTPS
     81  testSet.push(
     82    runTest({
     83      queryString: "test2.2",
     84      topLevelScheme: "https",
     85 
     86      expectedTopLevel: "https",
     87      expectedSameOrigin: "https",
     88      expectedCrossOrigin: "https",
     89    })
     90  );
     91 
     92  await Promise.all(testSet);
     93  testSet = [];
     94 
     95  /*
     96   * HTTPS-Only enabled, with exceptions
     97   * for http://example.org and http://example.com
     98   */
     99  // Exempting example.org (cross-site) should not affect anything
    100  await SpecialPowers.pushPermissions([
    101    {
    102      type: "https-only-load-insecure",
    103      allow: true,
    104      context: "http://example.org",
    105    },
    106  ]);
    107  await SpecialPowers.pushPermissions([
    108    {
    109      type: "https-only-load-insecure",
    110      allow: true,
    111      context: "http://example.com",
    112    },
    113  ]);
    114 
    115  // Top-Level scheme: HTTP
    116  await runTest({
    117    queryString: "test3.1",
    118    topLevelScheme: "http",
    119 
    120    expectedTopLevel: "http",
    121    expectedSameOrigin: "http",
    122    expectedCrossOrigin: "http",
    123  });
    124 
    125  await SpecialPowers.popPermissions();
    126  await SpecialPowers.pushPermissions([
    127    {
    128      type: "https-only-load-insecure",
    129      allow: true,
    130      context: "https://example.com",
    131    },
    132  ]);
    133  // Top-Level scheme: HTTPS
    134  await runTest({
    135    queryString: "test3.2",
    136    topLevelScheme: "https",
    137 
    138    expectedTopLevel: "https",
    139    expectedSameOrigin: "fail",
    140    expectedCrossOrigin: "fail",
    141  });
    142 
    143  // Remove permissions again (has to be done manually for some reason?)
    144  await SpecialPowers.popPermissions();
    145  await SpecialPowers.popPermissions();
    146 
    147  await evaluate();
    148 });
    149 
    150 const SERVER_URL = scheme =>
    151  `${scheme}://example.com/browser/dom/security/test/https-only/file_iframe_test.sjs?`;
    152 let shouldContain = [];
    153 let shouldNotContain = [];
    154 
    155 async function setup() {
    156  info(`TEST-CASE-setup - A`);
    157  const response = await fetch(SERVER_URL("https") + "setup");
    158  info(`TEST-CASE-setup - B`);
    159  const txt = await response.text();
    160  info(`TEST-CASE-setup - C`);
    161  if (txt != "ok") {
    162    ok(false, "Failed to setup test server.");
    163    finish();
    164  }
    165 }
    166 
    167 async function evaluate() {
    168  info(`TEST-CASE-evaluate - A`);
    169  const response = await fetch(SERVER_URL("https") + "results");
    170  info(`TEST-CASE-evaluate - B`);
    171  const requestResults = (await response.text()).split(";");
    172  info(`TEST-CASE-evaluate - C`);
    173 
    174  shouldContain.map(str =>
    175    ok(requestResults.includes(str), `Results should contain '${str}'.`)
    176  );
    177  shouldNotContain.map(str =>
    178    ok(!requestResults.includes(str), `Results shouldn't contain '${str}'.`)
    179  );
    180 }
    181 
    182 async function runTest(test) {
    183  const queryString = test.queryString;
    184  info(`TEST-CASE-${test.queryString} - runTest BEGIN`);
    185  await BrowserTestUtils.withNewTab("about:blank", async function (browser) {
    186    let loaded = BrowserTestUtils.browserLoaded(
    187      browser,
    188      false, // includeSubFrames
    189      SERVER_URL(test.expectedTopLevel) + queryString,
    190      false // maybeErrorPage
    191    );
    192    BrowserTestUtils.startLoadingURIString(
    193      browser,
    194      SERVER_URL(test.topLevelScheme) + queryString
    195    );
    196    info(`TEST-CASE-${test.queryString} - Before 'await loaded'`);
    197    await loaded;
    198    info(`TEST-CASE-${test.queryString} - After 'await loaded'`);
    199  });
    200  info(`TEST-CASE-${test.queryString} - After 'await withNewTab'`);
    201 
    202  if (test.expectedTopLevel !== "fail") {
    203    shouldContain.push(`top-${queryString}-${test.expectedTopLevel}`);
    204  } else {
    205    shouldNotContain.push(`top-${queryString}-http`);
    206    shouldNotContain.push(`top-${queryString}-https`);
    207  }
    208 
    209  if (test.expectedSameOrigin !== "fail") {
    210    shouldContain.push(`com-${queryString}-${test.expectedSameOrigin}`);
    211  } else {
    212    shouldNotContain.push(`com-${queryString}-http`);
    213    shouldNotContain.push(`com-${queryString}-https`);
    214  }
    215 
    216  if (test.expectedCrossOrigin !== "fail") {
    217    shouldContain.push(`org-${queryString}-${test.expectedCrossOrigin}`);
    218  } else {
    219    shouldNotContain.push(`org-${queryString}-http`);
    220    shouldNotContain.push(`org-${queryString}-https`);
    221  }
    222  info(`TEST-CASE-${test.queryString} - runTest END`);
    223 }