From 520a92573ce79e3628762e4ce06e284d50c2e548 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 21 May 2024 07:21:19 +0200 Subject: Merging upstream version 115.11.0esr. Signed-off-by: Daniel Baumann --- dom/security/nsHTTPSOnlyUtils.cpp | 6 +++ dom/security/nsHTTPSOnlyUtils.h | 12 +++++ dom/security/test/https-first/browser.ini | 4 ++ .../https-first/browser_subdocument_downgrade.js | 60 ++++++++++++++++++++++ dom/security/test/https-first/file_empty.html | 1 + .../https-first/file_subdocument_downgrade.sjs | 8 +++ 6 files changed, 91 insertions(+) create mode 100644 dom/security/test/https-first/browser_subdocument_downgrade.js create mode 100644 dom/security/test/https-first/file_empty.html create mode 100644 dom/security/test/https-first/file_subdocument_downgrade.sjs (limited to 'dom/security') diff --git a/dom/security/nsHTTPSOnlyUtils.cpp b/dom/security/nsHTTPSOnlyUtils.cpp index 8efbaea9ad..1eb5d057d9 100644 --- a/dom/security/nsHTTPSOnlyUtils.cpp +++ b/dom/security/nsHTTPSOnlyUtils.cpp @@ -808,6 +808,12 @@ bool nsHTTPSOnlyUtils::IsEqualURIExceptSchemeAndRef(nsIURI* aHTTPSSchemeURI, return uriEquals; } +/* static */ +uint32_t nsHTTPSOnlyUtils::GetStatusForSubresourceLoad( + uint32_t aHttpsOnlyStatus) { + return aHttpsOnlyStatus & ~nsILoadInfo::HTTPS_ONLY_UPGRADED_HTTPS_FIRST; +} + /*static*/ void nsHTTPSOnlyUtils::PotentiallyClearExemptFlag(nsILoadInfo* aLoadInfo) { // if neither HTTPS-Only nor HTTPS-First mode is enabled, then there is diff --git a/dom/security/nsHTTPSOnlyUtils.h b/dom/security/nsHTTPSOnlyUtils.h index 5cf94ae6a9..b25ef1fa96 100644 --- a/dom/security/nsHTTPSOnlyUtils.h +++ b/dom/security/nsHTTPSOnlyUtils.h @@ -163,6 +163,18 @@ class nsHTTPSOnlyUtils { nsIURI* aOtherURI, nsILoadInfo* aLoadInfo); + /** + * Determines which HTTPS-Only status flags should get propagated to + * sub-resources or sub-documents. As sub-resources and sub-documents are + * exempt when the top-level document is exempt, we need to copy the "exempt" + * flag. The HTTPS-First "upgraded" flag should not be copied to prevent a + * unwanted downgrade (Bug 1885949). + * @param aHttpsOnlyStatus The HTTPS-Only status of the top-level document. + * @return The HTTPS-Only status that the sub-resource/document should + * receive. + */ + static uint32_t GetStatusForSubresourceLoad(uint32_t aHttpsOnlyStatus); + /** * Checks a top-level load, if it is exempt by HTTPS-First/ Only * clear exemption flag. diff --git a/dom/security/test/https-first/browser.ini b/dom/security/test/https-first/browser.ini index 9e355423dc..3beeab3766 100644 --- a/dom/security/test/https-first/browser.ini +++ b/dom/security/test/https-first/browser.ini @@ -33,3 +33,7 @@ support-files = test.wav [browser_beforeunload_permit_http.js] support-files = file_beforeunload_permit_http.html +[browser_subdocument_downgrade.js] +support-files = + file_empty.html + file_subdocument_downgrade.sjs diff --git a/dom/security/test/https-first/browser_subdocument_downgrade.js b/dom/security/test/https-first/browser_subdocument_downgrade.js new file mode 100644 index 0000000000..4cb5b4ed2e --- /dev/null +++ b/dom/security/test/https-first/browser_subdocument_downgrade.js @@ -0,0 +1,60 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const EMPTY_URL = + "http://example.com/browser/dom/security/test/https-first/file_empty.html"; +const SUBDOCUMENT_URL = + "https://example.com/browser/dom/security/test/https-first/file_subdocument_downgrade.sjs"; + +add_task(async function test_subdocument_downgrade() { + await SpecialPowers.pushPrefEnv({ + set: [ + // We want to test HTTPS-First + ["dom.security.https_first", true], + // Makes it easier to detect the error + ["security.mixed_content.block_active_content", false], + ], + }); + + // Open a empty document with origin http://example.com, which gets upgraded + // to https://example.com by HTTPS-First and thus is marked as + // HTTPS_ONLY_UPGRADED_HTTPS_FIRST. + await BrowserTestUtils.withNewTab(EMPTY_URL, async browser => { + await SpecialPowers.spawn( + browser, + [SUBDOCUMENT_URL], + async SUBDOCUMENT_URL => { + function isCrossOriginIframe(iframe) { + try { + return !iframe.contentDocument; + } catch (e) { + return true; + } + } + const subdocument = content.document.createElement("iframe"); + // We open https://example.com/.../file_subdocument_downgrade.sjs in a + // iframe, which sends a invalid response if the scheme is https. Thus + // we should get an error. But if we accidentally copy the + // HTTPS_ONLY_UPGRADED_HTTPS_FIRST flag from the parent into the iframe + // loadinfo, HTTPS-First will try to downgrade the iframe. We test that + // this doesn't happen. + subdocument.src = SUBDOCUMENT_URL; + const loadPromise = new Promise(resolve => { + subdocument.addEventListener("load", () => { + ok( + // If the iframe got downgraded, it should now have the origin + // http://example.com, which we can detect as being cross-origin. + !isCrossOriginIframe(subdocument), + "Subdocument should not be downgraded" + ); + resolve(); + }); + }); + content.document.body.appendChild(subdocument); + await loadPromise; + } + ); + }); +}); diff --git a/dom/security/test/https-first/file_empty.html b/dom/security/test/https-first/file_empty.html new file mode 100644 index 0000000000..39d495653e --- /dev/null +++ b/dom/security/test/https-first/file_empty.html @@ -0,0 +1 @@ + diff --git a/dom/security/test/https-first/file_subdocument_downgrade.sjs b/dom/security/test/https-first/file_subdocument_downgrade.sjs new file mode 100644 index 0000000000..53ced94ba8 --- /dev/null +++ b/dom/security/test/https-first/file_subdocument_downgrade.sjs @@ -0,0 +1,8 @@ +function handleRequest(request, response) { + if (request.scheme === "https") { + response.setStatusLine("1.1", 429, "Too Many Requests"); + } else { + response.setHeader("Content-Type", "text/html", false); + response.write(""); + } +} -- cgit v1.2.3