Bug 1469714 - Part 10: Ensure that private browsing contexts cannot get storage access; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 12 Sep 2018 20:00:36 -0400
changeset 436827 62a37becb7a472876b6e7226ea9df2c3ca00886f
parent 436826 dacb7b20513cada99726ce57440961216dea04e4
child 436828 5f0d3c89e6c06e553d507ffa93ae64b656bc6260
push id34660
push userbtara@mozilla.com
push dateMon, 17 Sep 2018 21:58:52 +0000
treeherdermozilla-central@87a95e1b7ec6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1469714
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1469714 - Part 10: Ensure that private browsing contexts cannot get storage access; r=baku Differential Revision: https://phabricator.services.mozilla.com/D5819
dom/base/nsDocument.cpp
dom/base/nsGlobalWindowInner.cpp
toolkit/components/antitracking/AntiTrackingCommon.cpp
toolkit/components/antitracking/test/browser/browser.ini
toolkit/components/antitracking/test/browser/browser_storageAccessPrivateWindow.js
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -13666,16 +13666,23 @@ nsIDocument::RequestStorageAccess(mozill
     return promise.forget();
   }
 
   // Step 9. Check any additional rules that the browser has.
   //         Examples: Whitelists, blacklists, on-device classification,
   //         user settings, anti-clickjacking heuristics, or prompting the
   //         user for explicit permission. Reject if some rule is not fulfilled.
 
+  if (nsContentUtils::IsInPrivateBrowsing(this)) {
+    // If the document is in PB mode, it doesn't have access to its persistent
+    // cookie jar, so reject the promise here.
+    promise->MaybeRejectWithUndefined();
+    return promise.forget();
+  }
+
   bool granted = true;
   bool isTrackingWindow = false;
   if (StaticPrefs::browser_contentblocking_enabled() &&
       StaticPrefs::network_cookie_cookieBehavior() ==
         nsICookieService::BEHAVIOR_REJECT_TRACKER) {
     // Only do something special for third-party tracking content.
     if (nsContentUtils::StorageDisabledByAntiTracking(this, nullptr)) {
       isTrackingWindow = true;
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -6263,17 +6263,18 @@ nsGlobalWindowInner::GetTopLevelPrincipa
   }
 
   return topLevelPrincipal;
 }
 
 nsIPrincipal*
 nsGlobalWindowInner::GetTopLevelStorageAreaPrincipal()
 {
-  if (mDoc && (mDoc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS)) {
+  if (mDoc && ((mDoc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0 ||
+               nsContentUtils::IsInPrivateBrowsing(mDoc))) {
     // Storage access is disabled
     return nullptr;
   }
 
   nsPIDOMWindowOuter* outerWindow = GetParentInternal();
   if (!outerWindow) {
     // No outer window available!
     return nullptr;
--- a/toolkit/components/antitracking/AntiTrackingCommon.cpp
+++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp
@@ -62,17 +62,18 @@ bool
 GetParentPrincipalAndTrackingOrigin(nsGlobalWindowInner* a3rdPartyTrackingWindow,
                                     nsIPrincipal** aTopLevelStoragePrincipal,
                                     nsACString& aTrackingOrigin)
 {
   MOZ_ASSERT(nsContentUtils::IsTrackingResourceWindow(a3rdPartyTrackingWindow));
 
   nsIDocument* doc = a3rdPartyTrackingWindow->GetDocument();
   // Make sure storage access isn't disabled
-  if (doc && (doc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS)) {
+  if (doc && ((doc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0 ||
+              nsContentUtils::IsInPrivateBrowsing(doc))) {
     return false;
   }
 
   // Now we need the principal and the origin of the parent window.
   nsCOMPtr<nsIPrincipal> topLevelStoragePrincipal =
     a3rdPartyTrackingWindow->GetTopLevelStorageAreaPrincipal();
   if (NS_WARN_IF(!topLevelStoragePrincipal)) {
     return false;
--- a/toolkit/components/antitracking/test/browser/browser.ini
+++ b/toolkit/components/antitracking/test/browser/browser.ini
@@ -33,9 +33,10 @@ support-files = server.sjs
 [browser_onBeforeRequestNotificationForTrackingResources.js]
 [browser_onModifyRequestNotificationForTrackingResources.js]
 [browser_permissionInNormalWindows.js]
 [browser_permissionInPrivateWindows.js]
 [browser_subResources.js]
 support-files = subResources.sjs
 [browser_script.js]
 support-files = tracker.js
+[browser_storageAccessPrivateWindow.js]
 [browser_storageAccessSandboxed.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPrivateWindow.js
@@ -0,0 +1,36 @@
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+AntiTracking.runTest("Storage Access API called in a private window",
+  // blocking callback
+  async _ => {
+    let dwu = SpecialPowers.getDOMWindowUtils(window);
+    let helper = dwu.setHandlingUserInput(true);
+
+    let p;
+    let threw = false;
+    try {
+      p = document.requestStorageAccess();
+    } catch (e) {
+      threw = true;
+    } finally {
+      helper.destruct();
+    }
+    ok(!threw, "requestStorageAccess should not throw");
+    threw = false;
+    try {
+      await p;
+    } catch (e) {
+      threw = true;
+    }
+    ok(threw, "requestStorageAccess shouldn't be available");
+  },
+
+  null, // non-blocking callback
+  null, // cleanup function
+  [["dom.storage_access.enabled", true]], // extra prefs
+  false, // no window open test
+  false, // no user-interaction test
+  false, // no blocking notifications
+  true, // run in private window
+  null // iframe sandbox
+);