Bug 1515693 - Check allow-storage-access-by-user-activation sandbox flag only if StorageAccess API is enabled. r=ehsan, a=RyanVM
authorAndrea Marchesini <amarchesini@mozilla.com>
Sat, 22 Dec 2018 00:38:37 +0100
changeset 509165 3bd5407d62836b2435e6e241d751563129d150d9
parent 509164 d67ea56c71a28696c059691f5779916d72f6bc97
child 509166 2927c965fcf90c962d09b47b25a3d0fca6dff004
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, RyanVM
bugs1515693
milestone65.0
Bug 1515693 - Check allow-storage-access-by-user-activation sandbox flag only if StorageAccess API is enabled. r=ehsan, a=RyanVM
dom/base/nsDocument.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsIDocument.h
modules/libpref/init/StaticPrefList.h
netwerk/base/LoadInfo.cpp
toolkit/components/antitracking/AntiTrackingCommon.cpp
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12719,17 +12719,17 @@ already_AddRefed<mozilla::dom::Promise> 
       promise->MaybeResolveWithUndefined();
       return promise.forget();
     }
   }
 
   // Step 5. If the sub frame is not sandboxed, skip to step 7.
   // Step 6. If the sub frame doesn't have the token
   //         "allow-storage-access-by-user-activation", reject.
-  if (mSandboxFlags & SANDBOXED_STORAGE_ACCESS) {
+  if (StorageAccessSandboxed()) {
     promise->MaybeRejectWithUndefined();
     return promise.forget();
   }
 
   // Step 7. If the sub frame's parent frame is not the top frame, reject.
   nsIDocument* parent = GetParentDocument();
   if (parent && !parent->IsTopLevelContentDocument()) {
     promise->MaybeRejectWithUndefined();
@@ -12926,8 +12926,13 @@ void nsIDocument::ReportShadowDOMUsage()
                          NS_LITERAL_STRING("] or in some of its subdocuments.");
       nsContentUtils::ReportToConsoleNonLocalized(
           msg, nsIScriptError::infoFlag, NS_LITERAL_CSTRING("DOM"), topLevel);
     }
   }
 
   mHasReportedShadowDOMUsage = true;
 }
+
+bool nsIDocument::StorageAccessSandboxed() const {
+  return StaticPrefs::dom_storage_access_enabled() &&
+         (GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0;
+}
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -5800,17 +5800,17 @@ nsIPrincipal* nsGlobalWindowInner::GetTo
   if (NS_WARN_IF(!topLevelPrincipal)) {
     return nullptr;
   }
 
   return topLevelPrincipal;
 }
 
 nsIPrincipal* nsGlobalWindowInner::GetTopLevelStorageAreaPrincipal() {
-  if (mDoc && ((mDoc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0 ||
+  if (mDoc && (mDoc->StorageAccessSandboxed() ||
                nsContentUtils::IsInPrivateBrowsing(mDoc))) {
     // Storage access is disabled
     return nullptr;
   }
 
   nsPIDOMWindowOuter* outerWindow = GetParentInternal();
   if (!outerWindow) {
     // No outer window available!
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1287,16 +1287,20 @@ class nsIDocument : public nsINode,
   // Returns strong references to mBlockedTrackingNodes. (nsIDocument.h)
   //
   // This array contains nodes that have been blocked to prevent
   // user tracking. They most likely have had their nsIChannel
   // canceled by the URL classifier (Safebrowsing).
   //
   already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
 
+  // Helper method that returns true if the document has storage-access sandbox
+  // flag.
+  bool StorageAccessSandboxed() const;
+
  protected:
   friend class nsUnblockOnloadEvent;
 
   nsresult InitCSP(nsIChannel* aChannel);
 
   nsresult InitFeaturePolicy(nsIChannel* aChannel);
 
   void PostUnblockOnloadEvent();
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -463,16 +463,23 @@ VARCACHE_PREF(
 #endif
 VARCACHE_PREF(
   "dom.targetBlankNoOpener.enabled",
    dom_targetBlankNoOpener_enabled,
   bool, PREF_VALUE
 )
 #undef PREF_VALUE
 
+// Storage-access API.
+VARCACHE_PREF(
+  "dom.storage_access.enabled",
+   dom_storage_access_enabled,
+  bool, false
+)
+
 //---------------------------------------------------------------------------
 // Clear-Site-Data prefs
 //---------------------------------------------------------------------------
 
 VARCACHE_PREF(
   "dom.clearSiteData.enabled",
    dom_clearSiteData_enabled,
   bool, true
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -171,19 +171,18 @@ LoadInfo::LoadInfo(
         // 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))) {
+          if (!doc || (!doc->StorageAccessSandboxed() &&
+                       !nsContentUtils::IsInPrivateBrowsing(doc))) {
             mTopLevelStorageAreaPrincipal = innerWindow->GetPrincipal();
           }
         }
 
         mDocumentHasLoaded = innerWindow->IsDocumentLoaded();
 
         if (innerWindow->IsFrame()) {
           // For resources within iframes, we actually want the
--- a/toolkit/components/antitracking/AntiTrackingCommon.cpp
+++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp
@@ -69,17 +69,17 @@ bool GetParentPrincipalAndTrackingOrigin
     nsIURI** aTrackingURI, nsIPrincipal** aTrackingPrincipal) {
   if (!nsContentUtils::IsThirdPartyTrackingResourceWindow(
           a3rdPartyTrackingWindow)) {
     return false;
   }
 
   nsIDocument* doc = a3rdPartyTrackingWindow->GetDocument();
   // Make sure storage access isn't disabled
-  if (doc && ((doc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0 ||
+  if (doc && (doc->StorageAccessSandboxed() ||
               nsContentUtils::IsInPrivateBrowsing(doc))) {
     return false;
   }
 
   // Now we need the principal and the origin of the parent window.
   nsCOMPtr<nsIPrincipal> topLevelStoragePrincipal =
       a3rdPartyTrackingWindow->GetTopLevelStorageAreaPrincipal();
   if (!topLevelStoragePrincipal) {