Bug 1323644 - Isolate the HSTS and HPKP storage by first party domain (Necko) r=ckerschb
authorJonathan Hao <jhao@mozilla.com>
Tue, 14 Feb 2017 10:29:41 +0800
changeset 372883 821c937168828879c81515f8af19a21138551dab
parent 372882 1e40c75bc052bd0f2c86d72f1fe7494b06243eb7
child 372884 fe6f2e7b9aa15172ad599a8f6ef37b2cafd67df2
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersckerschb
bugs1323644
milestone54.0a1
Bug 1323644 - Isolate the HSTS and HPKP storage by first party domain (Necko) r=ckerschb MozReview-Commit-ID: 6DFPXTXoykc
netwerk/base/nsNetUtil.cpp
netwerk/base/nsNetUtil.h
netwerk/protocol/http/HSTSPrimerListener.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpHandler.cpp
--- 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);
 }