Bug 1804684 - Fragment navigation may change document URI scheme from https to http r=ckerschb

Differential Revision: https://phabricator.services.mozilla.com/D165282
This commit is contained in:
lyavor 2023-03-20 13:46:20 +00:00
Родитель f34bba48bf
Коммит 784f78bfb7
7 изменённых файлов: 41 добавлений и 13 удалений

Просмотреть файл

@ -8713,14 +8713,35 @@ bool nsDocShell::IsSameDocumentNavigation(nsDocShellLoadState* aLoadState,
// fact that the new URI is currently http), then set mSameExceptHashes to // fact that the new URI is currently http), then set mSameExceptHashes to
// true and only perform a fragment navigation. // true and only perform a fragment navigation.
if (!aState.mSameExceptHashes) { if (!aState.mSameExceptHashes) {
nsCOMPtr<nsIChannel> docChannel = GetCurrentDocChannel(); if (nsCOMPtr<nsIChannel> docChannel = GetCurrentDocChannel()) {
if (docChannel) {
nsCOMPtr<nsILoadInfo> docLoadInfo = docChannel->LoadInfo(); nsCOMPtr<nsILoadInfo> docLoadInfo = docChannel->LoadInfo();
if (!docLoadInfo->GetLoadErrorPage()) { if (!docLoadInfo->GetLoadErrorPage() &&
if (nsHTTPSOnlyUtils::IsEqualURIExceptSchemeAndRef( nsHTTPSOnlyUtils::IsEqualURIExceptSchemeAndRef(
currentExposableURI, aLoadState->URI(), docLoadInfo)) { currentExposableURI, aLoadState->URI(), docLoadInfo)) {
aState.mSameExceptHashes = true; uint32_t status = docLoadInfo->GetHttpsOnlyStatus();
if (status & (nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_REGISTERED |
nsILoadInfo::HTTPS_ONLY_UPGRADED_HTTPS_FIRST)) {
// At this point the requested URI is for sure a fragment
// navigation via HTTP and HTTPS-Only mode or HTTPS-First is
// enabled. Also it is not interfering the upgrade order of
// https://searchfox.org/mozilla-central/source/netwerk/base/nsNetUtil.cpp#2948-2953.
// Since we are on an HTTPS site the fragment
// navigation should also be an HTTPS.
// For that reason we upgrade the URI to HTTPS.
nsCOMPtr<nsIURI> upgradedURI;
NS_GetSecureUpgradedURI(aLoadState->URI(),
getter_AddRefs(upgradedURI));
aLoadState->SetURI(upgradedURI);
#ifdef DEBUG
bool sameExceptHashes = false;
currentExposableURI->EqualsExceptRef(aLoadState->URI(),
&sameExceptHashes);
MOZ_ASSERT(sameExceptHashes);
#endif
} }
aState.mSameExceptHashes = true;
} }
} }
} }

Просмотреть файл

@ -1062,6 +1062,9 @@ class nsDocShell final : public nsDocLoader,
// Check to see if we're loading a prior history entry or doing a fragment // Check to see if we're loading a prior history entry or doing a fragment
// navigation in the same document. // navigation in the same document.
// NOTE: In case we are doing a fragment navigation, and HTTPS-Only/ -First
// mode is enabled and upgraded the underlying document, we update the URI of
// aLoadState from HTTP to HTTPS (if neccessary).
bool IsSameDocumentNavigation(nsDocShellLoadState* aLoadState, bool IsSameDocumentNavigation(nsDocShellLoadState* aLoadState,
SameDocumentNavigationState& aState); SameDocumentNavigationState& aState);

Просмотреть файл

@ -26,8 +26,9 @@ window.onload = function (){
window.onscroll = function(){ window.onscroll = function(){
window.opener.postMessage({ window.opener.postMessage({
info: "scrolled-to-foo", info: "scrolled-to-foo",
result: window.location.hash, result: window.location.href,
button: true, button: true,
documentURI: document.documentURI,
}, "*"); }, "*");
} }

Просмотреть файл

@ -35,8 +35,9 @@ async function receiveMessage(event) {
// Once the button was clicked we know the tast has finished // Once the button was clicked we know the tast has finished
ok(data.button, "button is clicked"); ok(data.button, "button is clicked");
ok(data.result == "#foo", "location (hash) is correct"); is(data.result, EXPECT_URL + "#foo", "location (hash) is correct");
ok(data.info == "scrolled-to-foo","Scrolled successfully without reloading!"); ok(data.info == "scrolled-to-foo","Scrolled successfully without reloading!");
is(data.documentURI, EXPECT_URL + "#foo", "Document URI is correct");
window.removeEventListener("message",receiveMessage); window.removeEventListener("message",receiveMessage);
winTest.close(); winTest.close();
SimpleTest.finish(); SimpleTest.finish();

Просмотреть файл

@ -31,8 +31,9 @@ window.onload = function (){
window.onscroll = function(){ window.onscroll = function(){
window.opener.postMessage({ window.opener.postMessage({
info: "scrolled-to-foo", info: "scrolled-to-foo",
result: window.location.hash, result: window.location.href,
button: true, button: true,
documentURI: document.documentURI,
}, "*"); }, "*");
} }

Просмотреть файл

@ -27,6 +27,7 @@
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
const REQUEST_URL = "http://example.com/tests/dom/security/test/https-only/file_fragment.html"; const REQUEST_URL = "http://example.com/tests/dom/security/test/https-only/file_fragment.html";
const EXPECT_URL = REQUEST_URL.replace("http://", "https://");
let winTest = null; let winTest = null;
let checkButtonClicked = false; let checkButtonClicked = false;
@ -35,7 +36,7 @@ async function receiveMessage(event) {
// checks if click was successful // checks if click was successful
if (!checkButtonClicked){ if (!checkButtonClicked){
// expected window location ( expected URL) // expected window location ( expected URL)
ok(data.result == "https://example.com/tests/dom/security/test/https-only/file_fragment.html", "location is correct"); ok(data.result == EXPECT_URL, "location is correct");
ok(data.button, "button is clicked"); ok(data.button, "button is clicked");
// checks if loading was successful // checks if loading was successful
ok(data.info == "onload", "Onloading worked"); ok(data.info == "onload", "Onloading worked");
@ -46,9 +47,10 @@ async function receiveMessage(event) {
// if Button was clicked once -> test finished // if Button was clicked once -> test finished
// check if hash exist and if hash of location is correct // check if hash exist and if hash of location is correct
ok(data.button, "button is clicked"); ok(data.button, "button is clicked");
ok(data.result == "#foo", "location (hash) is correct"); ok(data.result == EXPECT_URL + "#foo", "location (hash) is correct");
// check that page is scrolled not reloaded // check that page is scrolled not reloaded
ok(data.info == "scrolled-to-foo","Scrolled successfully without reloading!"); ok(data.info == "scrolled-to-foo","Scrolled successfully without reloading!");
is(data.documentURI, EXPECT_URL + "#foo", "Document URI is correct");
// complete test and close window // complete test and close window
window.removeEventListener("message",receiveMessage); window.removeEventListener("message",receiveMessage);
winTest.close(); winTest.close();

Просмотреть файл

@ -495,8 +495,7 @@ interface nsILoadInfo : nsISupports
const unsigned long HTTPS_ONLY_DO_NOT_LOG_TO_CONSOLE = (1 << 6); const unsigned long HTTPS_ONLY_DO_NOT_LOG_TO_CONSOLE = (1 << 6);
/** /**
* This flag indicates that the request should not be logged to the * This flag indicates that the request was upgraded by https-first mode.
* console.
*/ */
const unsigned long HTTPS_ONLY_UPGRADED_HTTPS_FIRST = (1 << 7); const unsigned long HTTPS_ONLY_UPGRADED_HTTPS_FIRST = (1 << 7);