Bug 1323644 - Isolate the HSTS and HPKP storage by first party domain (Necko) r=mayhemer,ckerschb
MozReview-Commit-ID: 6DFPXTXoykc
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -2172,16 +2172,17 @@ NS_IsSrcdocChannel(nsIChannel *aChannel)
}
nsresult
NS_ShouldSecureUpgrade(nsIURI* aURI,
nsILoadInfo* aLoadInfo,
nsIPrincipal* aChannelResultPrincipal,
bool aPrivateBrowsing,
bool aAllowSTS,
+ const OriginAttributes& aOriginAttributes,
bool& aShouldUpgrade)
{
// Even if we're in private browsing mode, we still enforce existing STS
// data (it is read-only).
// if the connection is not using SSL and either the exact host matches or
// a superdomain wants to force HTTPS, do it.
bool isHttps = false;
nsresult rv = aURI->SchemeIs("https", &isHttps);
@@ -2230,17 +2231,17 @@ NS_ShouldSecureUpgrade(nsIURI* aURI,
// enforce Strict-Transport-Security
nsISiteSecurityService* sss = gHttpHandler->GetSSService();
NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
bool isStsHost = false;
uint32_t flags = aPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags,
- nullptr, &isStsHost);
+ aOriginAttributes, nullptr, &isStsHost);
// if the SSS check fails, it's likely because this load is on a
// malformed URI or something else in the setup is wrong, so any error
// should be reported.
NS_ENSURE_SUCCESS(rv, rv);
if (isStsHost) {
LOG(("nsHttpChannel::Connect() STS permissions found\n"));
--- a/netwerk/base/nsNetUtil.h
+++ b/netwerk/base/nsNetUtil.h
@@ -950,16 +950,17 @@ bool NS_IsValidHTTPToken(const nsACStrin
/**
* Return true if the given request must be upgraded to HTTPS.
*/
nsresult NS_ShouldSecureUpgrade(nsIURI* aURI,
nsILoadInfo* aLoadInfo,
nsIPrincipal* aChannelResultPrincipal,
bool aPrivateBrowsing,
bool aAllowSTS,
+ const mozilla::OriginAttributes& aOriginAttributes,
bool& aShouldUpgrade);
/**
* Returns an https URI for channels that need to go through secure upgrades.
*/
nsresult NS_GetSecureUpgradedURI(nsIURI* aURI, nsIURI** aUpgradedURI);
nsresult NS_CompareLoadInfoAndLoadContext(nsIChannel *aChannel);
--- a/netwerk/protocol/http/HSTSPrimerListener.cpp
+++ b/netwerk/protocol/http/HSTSPrimerListener.cpp
@@ -144,18 +144,22 @@ HSTSPrimingListener::CheckHSTSPrimingReq
nsCOMPtr<nsISiteSecurityService> sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = httpChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(uri, NS_ERROR_CONTENT_BLOCKED);
+ OriginAttributes originAttributes;
+ NS_GetOriginAttributes(httpChannel, originAttributes);
+
bool hsts;
- rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0, nullptr, &hsts);
+ rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0,
+ originAttributes, nullptr, &hsts);
NS_ENSURE_SUCCESS(rv, rv);
if (hsts) {
// An HSTS upgrade was found
return NS_OK;
}
// There is no HSTS upgrade available
@@ -217,17 +221,22 @@ HSTSPrimingListener::StartHSTSPriming(ns
rv = NS_GetSecureUpgradedURI(finalChannelURI, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv,rv);
// check the HSTS cache
bool hsts;
bool cached;
nsCOMPtr<nsISiteSecurityService> sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
- rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0, &cached, &hsts);
+
+ OriginAttributes originAttributes;
+ NS_GetOriginAttributes(aRequestChannel, originAttributes);
+
+ rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0,
+ originAttributes, &cached, &hsts);
NS_ENSURE_SUCCESS(rv, rv);
if (hsts) {
// already saw this host and will upgrade if allowed by preferences
return aCallback->OnHSTSPrimingSucceeded(true);
}
if (cached) {
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -2939,21 +2939,24 @@ HttpChannelChild::ShouldInterceptURI(nsI
bool isHttps = false;
nsresult rv = aURI->SchemeIs("https", &isHttps);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIPrincipal> resultPrincipal;
if (!isHttps && mLoadInfo) {
nsContentUtils::GetSecurityManager()->
GetChannelResultPrincipal(this, getter_AddRefs(resultPrincipal));
}
+ OriginAttributes originAttributes;
+ NS_ENSURE_TRUE(NS_GetOriginAttributes(this, originAttributes), false);
rv = NS_ShouldSecureUpgrade(aURI,
mLoadInfo,
resultPrincipal,
mPrivateBrowsing,
mAllowSTS,
+ originAttributes,
aShouldUpgrade);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIURI> upgradedURI;
if (aShouldUpgrade) {
rv = NS_GetSecureUpgradedURI(aURI, getter_AddRefs(upgradedURI));
NS_ENSURE_SUCCESS(rv, false);
}
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -384,22 +384,27 @@ nsHttpChannel::Connect()
bool isHttps = false;
rv = mURI->SchemeIs("https", &isHttps);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr<nsIPrincipal> resultPrincipal;
if (!isHttps && mLoadInfo) {
nsContentUtils::GetSecurityManager()->
GetChannelResultPrincipal(this, getter_AddRefs(resultPrincipal));
}
+ OriginAttributes originAttributes;
+ if (!NS_GetOriginAttributes(this, originAttributes)) {
+ return NS_ERROR_FAILURE;
+ }
bool shouldUpgrade = false;
rv = NS_ShouldSecureUpgrade(mURI,
mLoadInfo,
resultPrincipal,
mPrivateBrowsing,
mAllowSTS,
+ originAttributes,
shouldUpgrade);
NS_ENSURE_SUCCESS(rv, rv);
if (shouldUpgrade) {
return AsyncCall(&nsHttpChannel::HandleAsyncRedirectChannelToHttps);
}
// ensure that we are using a valid hostname
if (!net_IsValidHostName(nsDependentCString(mConnectionInfo->Origin())))
@@ -1628,19 +1633,22 @@ nsHttpChannel::ProcessSingleSecurityHead
nsAutoCString securityHeader;
nsresult rv = mResponseHead->GetHeader(atom, securityHeader);
if (NS_SUCCEEDED(rv)) {
nsISiteSecurityService* sss = gHttpHandler->GetSSService();
NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
// Process header will now discard the headers itself if the channel
// wasn't secure (whereas before it had to be checked manually)
+ OriginAttributes originAttributes;
+ NS_GetOriginAttributes(this, originAttributes);
uint32_t failureResult;
rv = sss->ProcessHeader(aType, mURI, securityHeader, aSSLStatus,
- aFlags, nullptr, nullptr, &failureResult);
+ aFlags, originAttributes, nullptr, nullptr,
+ &failureResult);
if (NS_FAILED(rv)) {
nsAutoString consoleErrorCategory;
nsAutoString consoleErrorTag;
switch (aType) {
case nsISiteSecurityService::HEADER_HSTS:
GetSTSConsoleErrorTag(failureResult, consoleErrorTag);
consoleErrorCategory = NS_LITERAL_STRING("Invalid HSTS Headers");
break;
@@ -8271,18 +8279,20 @@ nsHttpChannel::OnHSTSPrimingFailed(nsres
(wouldBlock) ? HSTSPrimingResult::eHSTS_PRIMING_FAILED_BLOCK :
HSTSPrimingResult::eHSTS_PRIMING_FAILED_ACCEPT);
}
// Don't visit again for at least
// security.mixed_content.hsts_priming_cache_timeout seconds.
nsISiteSecurityService* sss = gHttpHandler->GetSSService();
NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
+ OriginAttributes originAttributes;
+ NS_GetOriginAttributes(this, originAttributes);
nsresult rv = sss->CacheNegativeHSTSResult(mURI,
- nsMixedContentBlocker::sHSTSPrimingCacheTimeout);
+ nsMixedContentBlocker::sHSTSPrimingCacheTimeout, originAttributes);
if (NS_FAILED(rv)) {
NS_ERROR("nsISiteSecurityService::CacheNegativeHSTSResult failed");
}
// If we would block, go ahead and abort with the error provided
if (wouldBlock) {
CloseCacheEntry(false);
return AsyncAbort(aError);
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -2272,19 +2272,32 @@ nsHttpHandler::SpeculativeConnectInterna
bool isStsHost = false;
if (!sss)
return NS_OK;
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(aCallbacks);
uint32_t flags = 0;
if (loadContext && loadContext->UsePrivateBrowsing())
flags |= nsISocketProvider::NO_PERMANENT_STORAGE;
+
+ OriginAttributes originAttributes;
+ // If the principal is given, we use the originAttributes from this
+ // principal. Otherwise, we use the originAttributes from the
+ // loadContext.
+ if (aPrincipal) {
+ originAttributes.Inherit(aPrincipal->OriginAttributesRef());
+ } else if (loadContext) {
+ loadContext->GetOriginAttributes(originAttributes);
+ originAttributes.StripAttributes(OriginAttributes::STRIP_ADDON_ID);
+ }
+
nsCOMPtr<nsIURI> clone;
if (NS_SUCCEEDED(sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS,
- aURI, flags, nullptr, &isStsHost)) &&
+ aURI, flags, originAttributes,
+ nullptr, &isStsHost)) &&
isStsHost) {
if (NS_SUCCEEDED(NS_GetSecureUpgradedURI(aURI,
getter_AddRefs(clone)))) {
aURI = clone.get();
// (NOTE: We better make sure |clone| stays alive until the end
// of the function now, since our aURI arg now points to it!)
}
}
@@ -2320,27 +2333,16 @@ nsHttpHandler::SpeculativeConnectInterna
int32_t port = -1;
rv = aURI->GetPort(&port);
if (NS_FAILED(rv))
return rv;
nsAutoCString username;
aURI->GetUsername(username);
- OriginAttributes originAttributes;
- // If the principal is given, we use the originAttributes from this
- // principal. Otherwise, we use the originAttributes from the
- // loadContext.
- if (aPrincipal) {
- originAttributes.Inherit(aPrincipal->OriginAttributesRef());
- } else if (loadContext) {
- loadContext->GetOriginAttributes(originAttributes);
- originAttributes.StripAttributes(OriginAttributes::STRIP_ADDON_ID);
- }
-
auto *ci =
new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr,
originAttributes, usingSSL);
ci->SetAnonymous(anonymous);
return SpeculativeConnect(ci, aCallbacks);
}