Bug 1499995 - part 1 - LoadInfo must expose the correct top-level-storage-area-principal for sub documents, r=ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 25 Oct 2018 10:44:12 +0200
changeset 491255 a81dc13c90897abc468e8f70647a5c73b61a6017
parent 491254 ca965ec1bc91eb004ab8f5d89dc783e62ba04cf2
child 491256 ccd2e78000b8645cca3f3d028140e0b461ddc6be
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersehsan
bugs1499995
milestone65.0a1
Bug 1499995 - part 1 - LoadInfo must expose the correct top-level-storage-area-principal for sub documents, r=ehsan
netwerk/base/LoadInfo.cpp
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -23,16 +23,17 @@
 #include "nsISupportsImpl.h"
 #include "nsISupportsUtils.h"
 #include "nsIXPConnect.h"
 #include "nsContentUtils.h"
 #include "nsDocShell.h"
 #include "nsGlobalWindow.h"
 #include "nsMixedContentBlocker.h"
 #include "nsRedirectHistoryEntry.h"
+#include "nsSandboxFlags.h"
 #include "LoadInfo.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 namespace net {
 
 static uint64_t
@@ -128,16 +129,19 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
 
   // if the load is sandboxed, we can not also inherit the principal
   if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
     mForceInheritPrincipalDropped =
       (mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL);
     mSecurityFlags &= ~nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
 
+  uint32_t externalType =
+    nsContentUtils::InternalContentPolicyTypeToExternal(aContentPolicyType);
+
   if (aLoadingContext) {
     // Ensure that all network requests for a window client have the ClientInfo
     // properly set.  Workers must currently pass the loading ClientInfo explicitly.
     // We allow main thread requests to explicitly pass the value as well.
     if (mClientInfo.isNothing()) {
       mClientInfo = aLoadingContext->OwnerDoc()->GetClientInfo();
     }
 
@@ -157,18 +161,33 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
       nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
       mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
       mTopOuterWindowID = FindTopOuterWindowID(contextOuter);
 
       nsGlobalWindowInner* innerWindow =
         nsGlobalWindowInner::Cast(contextOuter->GetCurrentInnerWindow());
       if (innerWindow) {
         mTopLevelPrincipal = innerWindow->GetTopLevelPrincipal();
-        mTopLevelStorageAreaPrincipal =
-          innerWindow->GetTopLevelStorageAreaPrincipal();
+
+        // The top-level-storage-area-principal is not null only for the first
+        // level of iframes (null for top-level contexts, and null for
+        // sub-iframes). If we are loading a sub-document resource, we must
+        // calculate what the top-level-storage-area-principal will be for the
+        // new context.
+        if (externalType != nsIContentPolicy::TYPE_SUBDOCUMENT) {
+          mTopLevelStorageAreaPrincipal =
+            innerWindow->GetTopLevelStorageAreaPrincipal();
+        } else if (contextOuter->IsTopLevelWindow()) {
+          nsIDocument* doc = innerWindow->GetExtantDoc();
+          if (!doc || ((doc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) == 0 &&
+                       !nsContentUtils::IsInPrivateBrowsing(doc))) {
+            mTopLevelStorageAreaPrincipal = innerWindow->GetPrincipal();
+          }
+        }
+
         mDocumentHasLoaded = innerWindow->IsDocumentLoaded();
 
         if (innerWindow->IsFrame()) {
           // For resources within iframes, we actually want the
           // top-level document's flag, not the iframe document's.
           mDocumentHasLoaded = false;
           nsGlobalWindowOuter* topOuter = innerWindow->GetScriptableTopInternal();
           if (topOuter) {
@@ -212,18 +231,16 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
     // if the document forces all requests to be upgraded from http to https, then
     // we should do that for all requests. If it only forces preloads to be upgraded
     // then we should enforce upgrade insecure requests only for preloads.
     mUpgradeInsecureRequests =
       aLoadingContext->OwnerDoc()->GetUpgradeInsecureRequests(false) ||
       (nsContentUtils::IsPreloadType(mInternalContentPolicyType) &&
        aLoadingContext->OwnerDoc()->GetUpgradeInsecureRequests(true));
 
-    uint32_t externalType =
-      nsContentUtils::InternalContentPolicyTypeToExternal(mInternalContentPolicyType);
     if (nsContentUtils::IsUpgradableDisplayType(externalType)) {
       nsCOMPtr<nsIURI> uri;
       mLoadingPrincipal->GetURI(getter_AddRefs(uri));
       if (uri) {
         // Checking https not secure context as http://localhost can't be upgraded
         bool isHttpsScheme;
         nsresult rv = uri->SchemeIs("https", &isHttpsScheme);
         if (NS_SUCCEEDED(rv) && isHttpsScheme) {
@@ -370,18 +387,18 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
   nsCOMPtr<nsPIDOMWindowOuter> parent = aOuterWindow->GetScriptableParent();
   mParentOuterWindowID = parent ? parent->WindowID() : 0;
   mTopOuterWindowID = FindTopOuterWindowID(aOuterWindow);
 
   nsGlobalWindowInner* innerWindow =
     nsGlobalWindowInner::Cast(aOuterWindow->GetCurrentInnerWindow());
   if (innerWindow) {
     mTopLevelPrincipal = innerWindow->GetTopLevelPrincipal();
-    mTopLevelStorageAreaPrincipal =
-      innerWindow->GetTopLevelStorageAreaPrincipal();
+    // mTopLevelStorageAreaPrincipal is always null for top-level document
+    // loading.
   }
 
   // get the docshell from the outerwindow, and then get the originattributes
   nsCOMPtr<nsIDocShell> docShell = aOuterWindow->GetDocShell();
   MOZ_ASSERT(docShell);
   mOriginAttributes = nsDocShell::Cast(docShell)->GetOriginAttributes();
   mAncestorPrincipals = nsDocShell::Cast(docShell)->AncestorPrincipals();
   mAncestorOuterWindowIDs = nsDocShell::Cast(docShell)->AncestorOuterWindowIDs();