Bug 1391011: CSP: Fix upgrade-insecure-requests for toplevel navigations when base it https. r=smaug

This commit is contained in:
Christoph Kerschbaumer 2017-08-21 08:57:14 +02:00
parent ea0d7d9f2f
commit 9b81c8b695
2 changed files with 62 additions and 15 deletions

View File

@ -10879,6 +10879,62 @@ nsDocShell::GetInheritedPrincipal(bool aConsiderCurrentDocument)
return nullptr;
}
// CSPs upgrade-insecure-requests directive applies to same origin top level
// navigations. Using the SOP would return false for the case when an https
// page triggers and http page to load, even though that http page would be
// upgraded to https later. Hence we have to use that custom function instead
// of simply calling aTriggeringPrincipal->Equals(aResultPrincipal).
static bool
IsConsideredSameOriginForUIR(nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aResultPrincipal)
{
MOZ_ASSERT(aTriggeringPrincipal);
MOZ_ASSERT(aResultPrincipal);
// we only have to make sure that the following truth table holds:
// aTriggeringPrincipal | aResultPrincipal | Result
// ----------------------------------------------------------------
// http://example.com/foo.html | http://example.com/bar.html | true
// https://example.com/foo.html | https://example.com/bar.html | true
// https://example.com/foo.html | http://example.com/bar.html | true
if (aTriggeringPrincipal->Equals(aResultPrincipal)) {
return true;
}
if (!aResultPrincipal->GetIsCodebasePrincipal()) {
return false;
}
nsCOMPtr<nsIURI> resultURI;
nsresult rv = aResultPrincipal->GetURI(getter_AddRefs(resultURI));
NS_ENSURE_SUCCESS(rv, false);
nsAutoCString resultScheme;
rv = resultURI->GetScheme(resultScheme);
NS_ENSURE_SUCCESS(rv, false);
if (!resultScheme.EqualsLiteral("http")) {
return false;
}
nsAutoCString tmpResultSpec;
rv = resultURI->GetSpec(tmpResultSpec);
NS_ENSURE_SUCCESS(rv, false);
// replace http with https
tmpResultSpec.Replace(0, 4, "https");
nsCOMPtr<nsIURI> tmpResultURI;
rv = NS_NewURI(getter_AddRefs(tmpResultURI), tmpResultSpec);
NS_ENSURE_SUCCESS(rv, false);
mozilla::OriginAttributes tmpOA =
BasePrincipal::Cast(aResultPrincipal)->OriginAttributesRef();
nsCOMPtr<nsIPrincipal> tmpResultPrincipal =
BasePrincipal::CreateCodebasePrincipal(tmpResultURI, tmpOA);
return aTriggeringPrincipal->Equals(tmpResultPrincipal);
}
nsresult
nsDocShell::DoURILoad(nsIURI* aURI,
nsIURI* aOriginalURI,
@ -11173,7 +11229,7 @@ nsDocShell::DoURILoad(nsIURI* aURI,
GetChannelResultPrincipal(channel,
getter_AddRefs(resultPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
if (resultPrincipal->Equals(aTriggeringPrincipal)) {
if (IsConsideredSameOriginForUIR(aTriggeringPrincipal, resultPrincipal)) {
static_cast<mozilla::LoadInfo*>(loadInfo.get())->SetUpgradeInsecureRequests();
}
}

View File

@ -2578,21 +2578,12 @@ NS_ShouldSecureUpgrade(nsIURI* aURI,
NS_ENSURE_SUCCESS(rv, rv);
if (!isHttps) {
// If any of the documents up the chain to the root doucment makes use of
// the CSP directive 'upgrade-insecure-requests', then it's time to fulfill
// the promise to CSP and mixed content blocking to upgrade the channel
// from http to https.
if (aLoadInfo) {
// Please note that cross origin top level navigations are not subject
// to upgrade-insecure-requests, see:
// http://www.w3.org/TR/upgrade-insecure-requests/#examples
// Compare the principal we are navigating to (aChannelResultPrincipal)
// with the referring/triggering Principal.
bool crossOriginNavigation =
(aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT) &&
(!aChannelResultPrincipal->Equals(aLoadInfo->TriggeringPrincipal()));
if (aLoadInfo->GetUpgradeInsecureRequests() && !crossOriginNavigation) {
// If any of the documents up the chain to the root document makes use of
// the CSP directive 'upgrade-insecure-requests', then it's time to fulfill
// the promise to CSP and mixed content blocking to upgrade the channel
// from http to https.
if (aLoadInfo->GetUpgradeInsecureRequests()) {
// let's log a message to the console that we are upgrading a request
nsAutoCString scheme;
aURI->GetScheme(scheme);