Bug 1216365 - nsMixedContentBlocker should use innerMostURI for aContentLocation. r=tanvi
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Mon, 28 Mar 2016 22:03:26 -0700
changeset 290910 4d360ab12c65852cee305224701a024ec28e29e2
parent 290909 afbddd5fb6267ab5ad1446e6a7aaf723b97cac34
child 290911 ab6ca47677a8219cb08014f02fd41bc7dd83b9a4
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstanvi
bugs1216365
milestone48.0a1
Bug 1216365 - nsMixedContentBlocker should use innerMostURI for aContentLocation. r=tanvi
dom/security/nsMixedContentBlocker.cpp
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -495,16 +495,27 @@ nsMixedContentBlocker::ShouldLoad(bool a
 
 
     // This content policy works as a whitelist.
     default:
       MOZ_ASSERT(false, "Mixed content of unknown type");
       break;
   }
 
+  // Make sure to get the URI the load started with. No need to check
+  // outer schemes because all the wrapping pseudo protocols inherit the
+  // security properties of the actual network request represented
+  // by the innerMost URL.
+  nsCOMPtr<nsIURI> innerContentLocation = NS_GetInnermostURI(aContentLocation);
+  if (!innerContentLocation) {
+    NS_ERROR("Can't get innerURI from aContentLocation");
+    *aDecision = REJECT_REQUEST;
+    return NS_OK;
+  }
+
  /* Get the scheme of the sub-document resource to be requested. If it is
   * a safe to load in an https context then mixed content doesn't apply.
   *
   * Check Protocol Flags to determine if scheme is safe to load:
   * URI_DOES_NOT_RETURN_DATA - e.g.
   *   "mailto"
   * URI_IS_LOCAL_RESOURCE - e.g.
   *   "data",
@@ -516,26 +527,26 @@ nsMixedContentBlocker::ShouldLoad(bool a
   *   "https",
   *   "moz-safe-about"
   *
   */
   bool schemeLocal = false;
   bool schemeNoReturnData = false;
   bool schemeInherits = false;
   bool schemeSecure = false;
-  if (NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE , &schemeLocal))  ||
-      NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA, &schemeNoReturnData)) ||
-      NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT, &schemeInherits)) ||
-      NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT, &schemeSecure))) {
+  if (NS_FAILED(NS_URIChainHasFlags(innerContentLocation, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE , &schemeLocal))  ||
+      NS_FAILED(NS_URIChainHasFlags(innerContentLocation, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA, &schemeNoReturnData)) ||
+      NS_FAILED(NS_URIChainHasFlags(innerContentLocation, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT, &schemeInherits)) ||
+      NS_FAILED(NS_URIChainHasFlags(innerContentLocation, nsIProtocolHandler::URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT, &schemeSecure))) {
     *aDecision = REJECT_REQUEST;
     return NS_ERROR_FAILURE;
   }
   // TYPE_IMAGE redirects are cached based on the original URI, not the final
   // destination and hence cache hits for images may not have the correct
-  // aContentLocation.  Check if the cached hit went through an http redirect,
+  // innerContentLocation.  Check if the cached hit went through an http redirect,
   // and if it did, we can't treat this as a secure subresource.
   if (!aHadInsecureImageRedirect &&
       (schemeLocal || schemeNoReturnData || schemeInherits || schemeSecure)) {
     *aDecision = ACCEPT;
      return NS_OK;
   }
 
   // Since there are cases where aRequestingLocation and aRequestPrincipal are
@@ -609,24 +620,24 @@ nsMixedContentBlocker::ShouldLoad(bool a
   if (!requestingLocation) {
     *aDecision = REJECT_REQUEST;
     return NS_OK;
   }
 
   // Check the parent scheme. If it is not an HTTPS page then mixed content
   // restrictions do not apply.
   bool parentIsHttps;
-  nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(requestingLocation);
-  if (!innerURI) {
+  nsCOMPtr<nsIURI> innerRequestingLocation = NS_GetInnermostURI(requestingLocation);
+  if (!innerRequestingLocation) {
     NS_ERROR("Can't get innerURI from requestingLocation");
     *aDecision = REJECT_REQUEST;
     return NS_OK;
   }
 
-  nsresult rv = innerURI->SchemeIs("https", &parentIsHttps);
+  nsresult rv = innerRequestingLocation->SchemeIs("https", &parentIsHttps);
   if (NS_FAILED(rv)) {
     NS_ERROR("requestingLocation->SchemeIs failed");
     *aDecision = REJECT_REQUEST;
     return NS_OK;
   }
   if (!parentIsHttps) {
     *aDecision = ACCEPT;
     return NS_OK;
@@ -660,22 +671,22 @@ nsMixedContentBlocker::ShouldLoad(bool a
     *aDecision = REJECT_REQUEST;
     return NS_OK;
   }
 
   // Disallow mixed content loads for workers, shared workers and service
   // workers.
   if (isWorkerType) {
     // For workers, we can assume that we're mixed content at this point, since
-    // the parent is https, and the protocol associated with aContentLocation
+    // the parent is https, and the protocol associated with innerContentLocation
     // doesn't map to the secure URI flags checked above.  Assert this for
     // sanity's sake
 #ifdef DEBUG
     bool isHttpsScheme = false;
-    rv = aContentLocation->SchemeIs("https", &isHttpsScheme);
+    rv = innerContentLocation->SchemeIs("https", &isHttpsScheme);
     NS_ENSURE_SUCCESS(rv, rv);
     MOZ_ASSERT(!isHttpsScheme);
 #endif
     *aDecision = REJECT_REQUEST;
     return NS_OK;
   }
 
   // The page might have set the CSP directive 'upgrade-insecure-requests'. In such
@@ -685,17 +696,17 @@ nsMixedContentBlocker::ShouldLoad(bool a
   //
   // Please note that the CSP directive 'upgrade-insecure-requests' only applies to
   // http: and ws: (for websockets). Websockets are not subject to mixed content
   // blocking since insecure websockets are not allowed within secure pages. Hence,
   // we only have to check against http: here. Skip mixed content blocking if the
   // subresource load uses http: and the CSP directive 'upgrade-insecure-requests'
   // is present on the page.
   bool isHttpScheme = false;
-  rv = aContentLocation->SchemeIs("http", &isHttpScheme);
+  rv = innerContentLocation->SchemeIs("http", &isHttpScheme);
   NS_ENSURE_SUCCESS(rv, rv);
   if (isHttpScheme && docShell->GetDocument()->GetUpgradeInsecureRequests(isPreload)) {
     *aDecision = ACCEPT;
     return NS_OK;
   }
 
   // Determine if the rootDoc is https and if the user decided to allow Mixed Content
   bool rootHasSecureConnection = false;
@@ -782,23 +793,23 @@ nsMixedContentBlocker::ShouldLoad(bool a
   // is not blocked (e.g., for images).  For more detail, see:
   //   https://bugzilla.mozilla.org/show_bug.cgi?id=1198572#c19
   //
   // We do not count requests aHadInsecureImageRedirect=true, since these are
   // just an artifact of the image caching system.
   bool active = (classification == eMixedScript);
   if (!aHadInsecureImageRedirect) {
     if (XRE_IsParentProcess()) {
-      AccumulateMixedContentHSTS(aContentLocation, active);
+      AccumulateMixedContentHSTS(innerContentLocation, active);
     } else {
       // Ask the parent process to do the same call
       mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
       if (cc) {
         mozilla::ipc::URIParams uri;
-        SerializeURI(aContentLocation, uri);
+        SerializeURI(innerContentLocation, uri);
         cc->SendAccumulateMixedContentHSTS(uri, active);
       }
     }
   }
 
   // set hasMixedContentObjectSubrequest on this object if necessary
   if (aContentType == TYPE_OBJECT_SUBREQUEST) {
     rootDoc->SetHasMixedContentObjectSubrequest(true);