// Bug 1658264 - Https-Only: HTTPS-Only and iFrames // https://bugzilla.mozilla.org/show_bug.cgi?id=1658264 "use strict"; // > How does this test work? // We're sending a request to file_iframe_test.sjs with various // browser-configurations. The sjs-file returns a website with two iFrames // loading the same sjs-file again. One iFrame is same origin (example.com) and // the other cross-origin (example.org) Each request gets saved in a semicolon // seperated list of strings. The sjs-file gets initialized with the // query-string "setup" and the result string can be polled with "results". Each // string has this format: {top/com/org}-{queryString}-{scheme}. In the end // we're just checking if all expected requests were recorded and had the // correct scheme. Requests that are meant to fail should explicitly not be // contained in the list of results. // The test loads all tabs and evaluates when all have finished loading // it may take quite a long time. // This requires more twice as much as the default 45 seconds per test: requestLongerTimeout(2); SimpleTest.requestCompleteLog(); add_task(async function () { await setup(); // Using this variable to parallelize and collect tests let testSet = []; /* * HTTPS-Only Mode disabled */ await SpecialPowers.pushPrefEnv({ set: [["dom.security.https_only_mode", false]], }); // Top-Level scheme: HTTP // NOTE(freddyb): Test case temporarily disabled. See bug 1735565 /*testSet.push( runTest({ queryString: "test1.1", topLevelScheme: "http", expectedTopLevel: "http", expectedSameOrigin: "http", expectedCrossOrigin: "http", }) );*/ // Top-Level scheme: HTTPS testSet.push( runTest({ queryString: "test1.2", topLevelScheme: "https", expectedTopLevel: "https", expectedSameOrigin: "fail", expectedCrossOrigin: "fail", }) ); await Promise.all(testSet); testSet = []; /* * HTTPS-Only Mode enabled, no exception */ await SpecialPowers.pushPrefEnv({ set: [["dom.security.https_only_mode", true]], }); // Top-Level scheme: HTTP testSet.push( runTest({ queryString: "test2.1", topLevelScheme: "http", expectedTopLevel: "https", expectedSameOrigin: "https", expectedCrossOrigin: "https", }) ); // Top-Level scheme: HTTPS testSet.push( runTest({ queryString: "test2.2", topLevelScheme: "https", expectedTopLevel: "https", expectedSameOrigin: "https", expectedCrossOrigin: "https", }) ); await Promise.all(testSet); testSet = []; /* * HTTPS-Only enabled, with exceptions * for http://example.org and http://example.com */ // Exempting example.org (cross-site) should not affect anything await SpecialPowers.pushPermissions([ { type: "https-only-load-insecure", allow: true, context: "http://example.org", }, ]); await SpecialPowers.pushPermissions([ { type: "https-only-load-insecure", allow: true, context: "http://example.com", }, ]); // Top-Level scheme: HTTP await runTest({ queryString: "test3.1", topLevelScheme: "http", expectedTopLevel: "http", expectedSameOrigin: "http", expectedCrossOrigin: "http", }); await SpecialPowers.popPermissions(); await SpecialPowers.pushPermissions([ { type: "https-only-load-insecure", allow: true, context: "https://example.com", }, ]); // Top-Level scheme: HTTPS await runTest({ queryString: "test3.2", topLevelScheme: "https", expectedTopLevel: "https", expectedSameOrigin: "fail", expectedCrossOrigin: "fail", }); // Remove permissions again (has to be done manually for some reason?) await SpecialPowers.popPermissions(); await SpecialPowers.popPermissions(); await evaluate(); }); const SERVER_URL = scheme => `${scheme}://example.com/browser/dom/security/test/https-only/file_iframe_test.sjs?`; let shouldContain = []; let shouldNotContain = []; async function setup() { info(`TEST-CASE-setup - A`); const response = await fetch(SERVER_URL("https") + "setup"); info(`TEST-CASE-setup - B`); const txt = await response.text(); info(`TEST-CASE-setup - C`); if (txt != "ok") { ok(false, "Failed to setup test server."); finish(); } } async function evaluate() { info(`TEST-CASE-evaluate - A`); const response = await fetch(SERVER_URL("https") + "results"); info(`TEST-CASE-evaluate - B`); const requestResults = (await response.text()).split(";"); info(`TEST-CASE-evaluate - C`); shouldContain.map(str => ok(requestResults.includes(str), `Results should contain '${str}'.`) ); shouldNotContain.map(str => ok(!requestResults.includes(str), `Results shouldn't contain '${str}'.`) ); } async function runTest(test) { const queryString = test.queryString; info(`TEST-CASE-${test.queryString} - runTest BEGIN`); await BrowserTestUtils.withNewTab("about:blank", async function (browser) { let loaded = BrowserTestUtils.browserLoaded( browser, false, // includeSubFrames SERVER_URL(test.expectedTopLevel) + queryString, false // maybeErrorPage ); BrowserTestUtils.startLoadingURIString( browser, SERVER_URL(test.topLevelScheme) + queryString ); info(`TEST-CASE-${test.queryString} - Before 'await loaded'`); await loaded; info(`TEST-CASE-${test.queryString} - After 'await loaded'`); }); info(`TEST-CASE-${test.queryString} - After 'await withNewTab'`); if (test.expectedTopLevel !== "fail") { shouldContain.push(`top-${queryString}-${test.expectedTopLevel}`); } else { shouldNotContain.push(`top-${queryString}-http`); shouldNotContain.push(`top-${queryString}-https`); } if (test.expectedSameOrigin !== "fail") { shouldContain.push(`com-${queryString}-${test.expectedSameOrigin}`); } else { shouldNotContain.push(`com-${queryString}-http`); shouldNotContain.push(`com-${queryString}-https`); } if (test.expectedCrossOrigin !== "fail") { shouldContain.push(`org-${queryString}-${test.expectedCrossOrigin}`); } else { shouldNotContain.push(`org-${queryString}-http`); shouldNotContain.push(`org-${queryString}-https`); } info(`TEST-CASE-${test.queryString} - runTest END`); }