From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- dom/security/test/https-only/browser_hsts_host.js | 203 ++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 dom/security/test/https-only/browser_hsts_host.js (limited to 'dom/security/test/https-only/browser_hsts_host.js') diff --git a/dom/security/test/https-only/browser_hsts_host.js b/dom/security/test/https-only/browser_hsts_host.js new file mode 100644 index 0000000000..858c19865c --- /dev/null +++ b/dom/security/test/https-only/browser_hsts_host.js @@ -0,0 +1,203 @@ +// Bug 1722489 - HTTPS-Only Mode - Tests evaluation order +// https://bugzilla.mozilla.org/show_bug.cgi?id=1722489 +// This test ensures that an http request to an hsts host +// gets upgraded by hsts and not by https-only. +"use strict"; + +// Set bools to track that tests ended. +let readMessage = false; +let testFinished = false; +// Visit a secure site that sends an HSTS header to set up the rest of the +// test. +add_task(async function see_hsts_header() { + let setHstsUrl = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" + ) + "hsts_headers.sjs"; + Services.obs.addObserver(observer, "http-on-examine-response"); + + let promiseLoaded = BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + false, + setHstsUrl + ); + BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, setHstsUrl); + await promiseLoaded; + + await BrowserTestUtils.waitForCondition(() => readMessage); + // Clean up + Services.obs.removeObserver(observer, "http-on-examine-response"); +}); + +// Test that HTTPS_Only is not performed if HSTS host is visited. +add_task(async function () { + // A longer timeout is necessary for this test than the plain mochitests + // due to opening a new tab with the web console. + requestLongerTimeout(4); + + // Enable HTTPS-Only Mode and register console-listener + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_only_mode", true]], + }); + + Services.console.registerListener(onNewMessage); + const RESOURCE_LINK = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" + ) + "hsts_headers.sjs"; + + // 1. Upgrade page to https:// + let promiseLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString( + gBrowser.selectedBrowser, + RESOURCE_LINK + ); + await promiseLoaded; + + await BrowserTestUtils.waitForCondition(() => testFinished); + + // Clean up + Services.console.unregisterListener(onNewMessage); + + await SpecialPowers.popPrefEnv(); +}); + +// Test that when clicking on #fragment with a different scheme (http vs https) +// DOES cause an actual navigation with HSTS, even though https-only mode is +// enabled. +add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.security.https_only_mode", true], + [ + "dom.security.https_only_mode_break_upgrade_downgrade_endless_loop", + false, + ], + ], + }); + + const TEST_PAGE = + "http://example.com/browser/dom/security/test/https-only/file_fragment_noscript.html"; + + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: TEST_PAGE, + waitForLoad: true, + }, + async function (browser) { + const UPGRADED_URL = TEST_PAGE.replace("http:", "https:"); + + await SpecialPowers.spawn(browser, [UPGRADED_URL], async function (url) { + is(content.window.location.href, url); + + content.window.addEventListener("scroll", () => { + ok(false, "scroll event should not trigger"); + }); + + let beforeUnload = new Promise(resolve => { + content.window.addEventListener("beforeunload", resolve, { + once: true, + }); + }); + + content.window.document.querySelector("#clickMeButton").click(); + + // Wait for unload event. + await beforeUnload; + }); + + await BrowserTestUtils.browserLoaded(browser); + + await SpecialPowers.spawn(browser, [UPGRADED_URL], async function (url) { + is(content.window.location.href, url + "#foo"); + }); + } + ); + + await SpecialPowers.popPrefEnv(); +}); + +add_task(async function () { + // Reset HSTS header + readMessage = false; + let clearHstsUrl = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" + ) + "hsts_headers.sjs?reset"; + + Services.obs.addObserver(observer, "http-on-examine-response"); + // reset hsts header + let promiseLoaded = BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + false, + clearHstsUrl + ); + await BrowserTestUtils.startLoadingURIString( + gBrowser.selectedBrowser, + clearHstsUrl + ); + await promiseLoaded; + await BrowserTestUtils.waitForCondition(() => readMessage); + // Clean up + Services.obs.removeObserver(observer, "http-on-examine-response"); +}); + +function observer(subject, topic, state) { + info("observer called with " + topic); + if (topic == "http-on-examine-response") { + onExamineResponse(subject); + } +} + +function onExamineResponse(subject) { + let channel = subject.QueryInterface(Ci.nsIHttpChannel); + // If message was already read or is not related to "example.com", + // don't examine it. + if (!channel.URI.spec.includes("example.com") || readMessage) { + return; + } + info("onExamineResponse with " + channel.URI.spec); + if (channel.URI.spec.includes("reset")) { + try { + let hsts = channel.getResponseHeader("Strict-Transport-Security"); + is(hsts, "max-age=0", "HSTS header is not set"); + } catch (e) { + ok(false, "HSTS header still set"); + } + readMessage = true; + return; + } + try { + let hsts = channel.getResponseHeader("Strict-Transport-Security"); + let csp = channel.getResponseHeader("Content-Security-Policy"); + // Check that HSTS and CSP upgrade headers are set + is(hsts, "max-age=60", "HSTS header is set"); + is(csp, "upgrade-insecure-requests", "CSP header is set"); + } catch (e) { + ok(false, "No header set"); + } + readMessage = true; +} + +function onNewMessage(msgObj) { + const message = msgObj.message; + // ensure that request is not upgraded HTTPS-Only. + if (message.includes("Upgrading insecure request")) { + ok(false, "Top-Level upgrade shouldn't get logged"); + testFinished = true; + } else if ( + message.includes("Upgrading insecure speculative TCP connection") + ) { + // TODO: Check assertion + // https://bugzilla.mozilla.org/show_bug.cgi?id=1735683 + ok(true, "Top-Level upgrade shouldn't get logged"); + testFinished = true; + } else if (gBrowser.selectedBrowser.currentURI.scheme === "https") { + ok(true, "Top-Level upgrade shouldn't get logged"); + testFinished = true; + } +} -- cgit v1.2.3