Loading dom/security/nsHTTPSOnlyUtils.cpp +31 −4 Original line number Diff line number Diff line Loading @@ -498,15 +498,42 @@ nsHTTPSOnlyUtils::PotentiallyDowngradeHttpsFirstRequest(nsIChannel* aChannel, nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, nullptr); // Only downgrade if the current scheme is HTTPS if (!uri->SchemeIs("https")) { // Only downgrade if the current scheme is (a) https or (b) view-source:https nsAutoCString spec; if (uri->SchemeIs("https")) { rv = uri->GetSpec(spec); NS_ENSURE_SUCCESS(rv, nullptr); } else if (uri->SchemeIs("view-source")) { nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(uri); if (!nestedURI) { return nullptr; } nsCOMPtr<nsIURI> innerURI; rv = nestedURI->GetInnerURI(getter_AddRefs(innerURI)); NS_ENSURE_SUCCESS(rv, nullptr); if (!innerURI || !innerURI->SchemeIs("https")) { return nullptr; } nsAutoCString innerSpec; rv = innerURI->GetSpec(innerSpec); NS_ENSURE_SUCCESS(rv, nullptr); spec.Append("view-source:"); spec.Append(innerSpec); } else { return nullptr; } // Change the scheme to http if (spec.Find("https://") < 0) { MOZ_ASSERT(false, "how can we end up here not dealing with an https: URI?"); return nullptr; } spec.ReplaceSubstring("https://", "http://"); nsCOMPtr<nsIURI> newURI; mozilla::Unused << NS_MutateURI(uri).SetScheme("http"_ns).Finalize( getter_AddRefs(newURI)); rv = NS_NewURI(getter_AddRefs(newURI), spec); NS_ENSURE_SUCCESS(rv, nullptr); // Log downgrade to console NS_ConvertUTF8toUTF16 reportSpec(uri->GetSpecOrDefault()); Loading dom/security/test/https-first/browser.ini +2 −0 Original line number Diff line number Diff line Loading @@ -6,3 +6,5 @@ support-files = [browser_mixed_content_console.js] support-files = file_mixed_content_console.html [browser_downgrade_view_source.js] support-files = file_downgrade_view_source.sjs dom/security/test/https-first/browser_downgrade_view_source.js 0 → 100644 +53 −0 Original line number Diff line number Diff line // This test ensures that view-source:https falls back to view-source:http "use strict"; const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "http://example.com" ); const TEST_PATH_HTTPS = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://example.com" ); async function runTest(desc, url, expectedURI, excpectedContent) { await BrowserTestUtils.withNewTab("about:blank", async function(browser) { let loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); BrowserTestUtils.loadURI(browser, url); await loaded; await SpecialPowers.spawn( browser, [desc, expectedURI, excpectedContent], async function(desc, expectedURI, excpectedContent) { let loadedURI = content.document.documentURI; is(loadedURI, expectedURI, desc); let loadedContent = content.document.body.textContent; is(loadedContent, excpectedContent, desc); } ); }); } add_task(async function() { requestLongerTimeout(2); await SpecialPowers.pushPrefEnv({ set: [["dom.security.https_first", true]], }); await runTest( "URL with query 'downgrade' should be http:", `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade`, `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade`, "view-source:http://" ); await runTest( "URL with query 'upgrade' should be https:", `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?upgrade`, `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade`, "view-source:https://" ); }); dom/security/test/https-first/file_downgrade_view_source.sjs 0 → 100644 +30 −0 Original line number Diff line number Diff line "use strict"; function handleRequest(request, response) { // avoid confusing cache behaviour response.setHeader("Cache-Control", "no-cache", false); response.setHeader("Content-Type", "text/html", false); let query = request.queryString; let scheme = request.scheme; if (scheme === "https") { if (query === "downgrade") { response.setStatusLine("1.1", 400, "Bad Request"); response.write("Bad Request\n"); return; } if (query === "upgrade") { response.write("view-source:https://"); return; } } if (scheme === "http" && query === "downgrade") { response.write("view-source:http://"); return; } // We should arrive here when the redirection was downraded successful response.write("unexpected"); } Loading
dom/security/nsHTTPSOnlyUtils.cpp +31 −4 Original line number Diff line number Diff line Loading @@ -498,15 +498,42 @@ nsHTTPSOnlyUtils::PotentiallyDowngradeHttpsFirstRequest(nsIChannel* aChannel, nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, nullptr); // Only downgrade if the current scheme is HTTPS if (!uri->SchemeIs("https")) { // Only downgrade if the current scheme is (a) https or (b) view-source:https nsAutoCString spec; if (uri->SchemeIs("https")) { rv = uri->GetSpec(spec); NS_ENSURE_SUCCESS(rv, nullptr); } else if (uri->SchemeIs("view-source")) { nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(uri); if (!nestedURI) { return nullptr; } nsCOMPtr<nsIURI> innerURI; rv = nestedURI->GetInnerURI(getter_AddRefs(innerURI)); NS_ENSURE_SUCCESS(rv, nullptr); if (!innerURI || !innerURI->SchemeIs("https")) { return nullptr; } nsAutoCString innerSpec; rv = innerURI->GetSpec(innerSpec); NS_ENSURE_SUCCESS(rv, nullptr); spec.Append("view-source:"); spec.Append(innerSpec); } else { return nullptr; } // Change the scheme to http if (spec.Find("https://") < 0) { MOZ_ASSERT(false, "how can we end up here not dealing with an https: URI?"); return nullptr; } spec.ReplaceSubstring("https://", "http://"); nsCOMPtr<nsIURI> newURI; mozilla::Unused << NS_MutateURI(uri).SetScheme("http"_ns).Finalize( getter_AddRefs(newURI)); rv = NS_NewURI(getter_AddRefs(newURI), spec); NS_ENSURE_SUCCESS(rv, nullptr); // Log downgrade to console NS_ConvertUTF8toUTF16 reportSpec(uri->GetSpecOrDefault()); Loading
dom/security/test/https-first/browser.ini +2 −0 Original line number Diff line number Diff line Loading @@ -6,3 +6,5 @@ support-files = [browser_mixed_content_console.js] support-files = file_mixed_content_console.html [browser_downgrade_view_source.js] support-files = file_downgrade_view_source.sjs
dom/security/test/https-first/browser_downgrade_view_source.js 0 → 100644 +53 −0 Original line number Diff line number Diff line // This test ensures that view-source:https falls back to view-source:http "use strict"; const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "http://example.com" ); const TEST_PATH_HTTPS = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://example.com" ); async function runTest(desc, url, expectedURI, excpectedContent) { await BrowserTestUtils.withNewTab("about:blank", async function(browser) { let loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); BrowserTestUtils.loadURI(browser, url); await loaded; await SpecialPowers.spawn( browser, [desc, expectedURI, excpectedContent], async function(desc, expectedURI, excpectedContent) { let loadedURI = content.document.documentURI; is(loadedURI, expectedURI, desc); let loadedContent = content.document.body.textContent; is(loadedContent, excpectedContent, desc); } ); }); } add_task(async function() { requestLongerTimeout(2); await SpecialPowers.pushPrefEnv({ set: [["dom.security.https_first", true]], }); await runTest( "URL with query 'downgrade' should be http:", `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade`, `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade`, "view-source:http://" ); await runTest( "URL with query 'upgrade' should be https:", `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?upgrade`, `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade`, "view-source:https://" ); });
dom/security/test/https-first/file_downgrade_view_source.sjs 0 → 100644 +30 −0 Original line number Diff line number Diff line "use strict"; function handleRequest(request, response) { // avoid confusing cache behaviour response.setHeader("Cache-Control", "no-cache", false); response.setHeader("Content-Type", "text/html", false); let query = request.queryString; let scheme = request.scheme; if (scheme === "https") { if (query === "downgrade") { response.setStatusLine("1.1", 400, "Bad Request"); response.write("Bad Request\n"); return; } if (query === "upgrade") { response.write("view-source:https://"); return; } } if (scheme === "http" && query === "downgrade") { response.write("view-source:http://"); return; } // We should arrive here when the redirection was downraded successful response.write("unexpected"); }