Bug 1547813 - Part 3: Modify the antitracking algorithms to work with nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN; r=baku
☠☠ backed out by 8fea66166287 ☠ ☠
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 09 May 2019 14:00:55 +0000
changeset 532056 b4651cfaff307a7f3f05538907045b1e24a07923
parent 532055 279c140a4d71c537afd5eee36f3b9262f97c819b
child 532057 77a040f527e9903657ccc0910adb760aef281619
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1547813
milestone68.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 1547813 - Part 3: Modify the antitracking algorithms to work with nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN; r=baku The policy that this patch implements in the antitracking backend is to treat third-party trackers exactly the same way as BEHAVIOR_REJECT_TRACKER, and additionally partition all third-party contexts as well. Differential Revision: https://phabricator.services.mozilla.com/D29738
toolkit/components/antitracking/AntiTrackingCommon.cpp
--- a/toolkit/components/antitracking/AntiTrackingCommon.cpp
+++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp
@@ -420,16 +420,18 @@ void ReportBlockingToConsole(nsPIDOMWind
                              uint32_t aRejectedReason) {
   MOZ_ASSERT(aWindow && aURI);
   MOZ_ASSERT(
       aRejectedReason == 0 ||
       aRejectedReason ==
           nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
       aRejectedReason ==
           nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
+      aRejectedReason ==
+          nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
 
   nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
   if (NS_WARN_IF(!docShell)) {
     return;
   }
 
@@ -1183,18 +1185,21 @@ bool AntiTrackingCommon::IsFirstPartySto
   if (behavior == nsICookieService::BEHAVIOR_REJECT) {
     LOG(("The cookie behavior pref mandates rejecting all cookies!"));
     *aRejectedReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL;
     return false;
   }
 
   // As a performance optimization, we only perform this check for
   // BEHAVIOR_REJECT_FOREIGN and BEHAVIOR_LIMIT_FOREIGN.  For
-  // BEHAVIOR_REJECT_TRACKER, third-partiness is implicily checked later below.
-  if (behavior != nsICookieService::BEHAVIOR_REJECT_TRACKER) {
+  // BEHAVIOR_REJECT_TRACKER and BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
+  // third-partiness is implicily checked later below.
+  if (behavior != nsICookieService::BEHAVIOR_REJECT_TRACKER &&
+      behavior !=
+          nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN) {
     // Let's check if this is a 3rd party context.
     if (!nsContentUtils::IsThirdPartyWindowOrChannel(aWindow, nullptr, aURI)) {
       LOG(("Our window isn't a third-party window"));
       return true;
     }
   }
 
   if (behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
@@ -1203,21 +1208,41 @@ bool AntiTrackingCommon::IsFirstPartySto
     // simply rejecting the request to use the storage. In the future, if we
     // change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
     // for non-cookie storage types, this may change.
     LOG(("Nothing more to do due to the behavior code %d", int(behavior)));
     *aRejectedReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN;
     return false;
   }
 
-  MOZ_ASSERT(behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER);
+  MOZ_ASSERT(
+      behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER ||
+      behavior ==
+          nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN);
 
-  if (!nsContentUtils::IsThirdPartyTrackingResourceWindow(aWindow)) {
-    LOG(("Our window isn't a third-party tracking window"));
-    return true;
+  if (behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER) {
+    if (!nsContentUtils::IsThirdPartyTrackingResourceWindow(aWindow)) {
+      LOG(("Our window isn't a third-party tracking window"));
+      return true;
+    }
+  } else {
+    MOZ_ASSERT(behavior ==
+               nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN);
+    if (nsContentUtils::IsThirdPartyTrackingResourceWindow(aWindow)) {
+      // fall through
+    } else if (nsContentUtils::IsThirdPartyWindowOrChannel(aWindow, nullptr,
+                                                           aURI)) {
+      LOG(("We're in the third-party context, storage should be partitioned"));
+      *aRejectedReason =
+          nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN;
+      return false;
+    } else {
+      LOG(("Our window isn't a third-party window, storage is allowed"));
+      return true;
+    }
   }
 
 #ifdef DEBUG
   nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
   if (thirdPartyUtil) {
     bool thirdParty = false;
     nsresult rv = thirdPartyUtil->IsThirdPartyWindow(aWindow->GetOuterWindow(),
                                                      aURI, &thirdParty);
@@ -1440,22 +1465,42 @@ bool AntiTrackingCommon::IsFirstPartySto
     // simply rejecting the request to use the storage. In the future, if we
     // change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
     // for non-cookie storage types, this may change.
     LOG(("Nothing more to do due to the behavior code %d", int(behavior)));
     *aRejectedReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN;
     return false;
   }
 
-  MOZ_ASSERT(behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER);
+  MOZ_ASSERT(
+      behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER ||
+      behavior ==
+          nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN);
 
   // Not a tracker.
-  if (!aChannel->IsThirdPartyTrackingResource()) {
-    LOG(("Our channel isn't a third-party tracking channel"));
-    return true;
+  if (behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER) {
+    if (!aChannel->IsThirdPartyTrackingResource()) {
+      LOG(("Our channel isn't a third-party tracking channel"));
+      return true;
+    }
+  } else {
+    MOZ_ASSERT(behavior ==
+               nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN);
+    if (aChannel->IsThirdPartyTrackingResource()) {
+      // fall through
+    } else if (nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel,
+                                                           aURI)) {
+      LOG(("We're in the third-party context, storage should be partitioned"));
+      *aRejectedReason =
+          nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN;
+      return false;
+    } else {
+      LOG(("Our channel isn't a third-party channel, storage is allowed"));
+      return true;
+    }
   }
 
   nsIPrincipal* parentPrincipal = loadInfo->GetTopLevelStorageAreaPrincipal();
   if (!parentPrincipal) {
     LOG(("No top-level storage area principal at hand"));
 
     // parentPrincipal can be null if the parent window is not the top-level
     // window.
@@ -1568,16 +1613,18 @@ bool AntiTrackingCommon::MaybeIsFirstPar
   Document* parentDocument =
       nsGlobalWindowInner::Cast(aFirstPartyWindow)->GetExtantDoc();
   if (NS_WARN_IF(!parentDocument)) {
     LOG(("Failed to get the first party window's document"));
     return false;
   }
 
   auto cookieBehavior = parentDocument->CookieSettings()->GetCookieBehavior();
+  // TODO: Perhaps we need to do something special for
+  // nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN here?
   if (cookieBehavior != nsICookieService::BEHAVIOR_REJECT_TRACKER) {
     LOG(("Disabled by the pref (%d), bail out early", cookieBehavior));
     return true;
   }
 
   if (CheckContentBlockingAllowList(aFirstPartyWindow)) {
     return true;
   }
@@ -1719,16 +1766,18 @@ void AntiTrackingCommon::NotifyBlockingD
                                                 BlockingDecision aDecision,
                                                 uint32_t aRejectedReason) {
   MOZ_ASSERT(
       aRejectedReason == 0 ||
       aRejectedReason ==
           nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
       aRejectedReason ==
           nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
+      aRejectedReason ==
+          nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
   MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
              aDecision == BlockingDecision::eAllow);
 
   if (!aChannel) {
     return;
   }
@@ -1787,16 +1836,18 @@ void AntiTrackingCommon::NotifyBlockingD
                                                 uint32_t aRejectedReason) {
   MOZ_ASSERT(aWindow);
   MOZ_ASSERT(
       aRejectedReason == 0 ||
       aRejectedReason ==
           nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
       aRejectedReason ==
           nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
+      aRejectedReason ==
+          nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
   MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
              aDecision == BlockingDecision::eAllow);
 
   nsCOMPtr<nsPIDOMWindowOuter> pwin = GetTopWindow(aWindow);
   if (!pwin) {
     return;