Bug 1486926 - Part 1: Make the Disable Protection button in the control centre UI work for the reject foreign cookie behavior; r=baku
☠☠ backed out by b6be51ee00aa ☠ ☠
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 25 Aug 2018 02:48:50 -0400
changeset 482170 20f625526901c263f3a3cf5bddae0dce664f93a7
parent 482169 9ddd9b9a99191879a5faffcb161f485c85797116
child 482171 f6533c40954fc95bcd470a9e2662d928fe42df9e
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewersbaku
bugs1486926
milestone63.0a1
Bug 1486926 - Part 1: Make the Disable Protection button in the control centre UI work for the reject foreign cookie behavior; r=baku
netwerk/cookie/CookieServiceChild.cpp
netwerk/cookie/CookieServiceParent.cpp
netwerk/cookie/nsCookieService.cpp
toolkit/components/antitracking/AntiTrackingCommon.cpp
--- a/netwerk/cookie/CookieServiceChild.cpp
+++ b/netwerk/cookie/CookieServiceChild.cpp
@@ -178,17 +178,20 @@ CookieServiceChild::TrackCookieLoad(nsIC
   nsCOMPtr<nsIURI> uri;
   aChannel->GetURI(getter_AddRefs(uri));
   if (RequireThirdPartyCheck()) {
     mThirdPartyUtil->IsThirdPartyChannel(aChannel, uri, &isForeign);
   }
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   if (httpChannel) {
     isTrackingResource = httpChannel->GetIsTrackingResource();
-    if (isForeign && isTrackingResource &&
+    // Check first-party storage access even for non-tracking resources, since
+    // we will need the result when computing the access rights for the reject
+    // foreign cookie behavior mode.
+    if (isForeign &&
         AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
                                                                 uri)) {
       firstPartyStorageAccessGranted = true;
     }
   }
   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
   mozilla::OriginAttributes attrs;
   if (loadInfo) {
@@ -576,17 +579,20 @@ CookieServiceChild::GetCookieStringInter
   if (RequireThirdPartyCheck())
     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
 
   bool isTrackingResource = false;
   bool firstPartyStorageAccessGranted = false;
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   if (httpChannel) {
     isTrackingResource = httpChannel->GetIsTrackingResource();
-    if (isForeign && isTrackingResource &&
+    // Check first-party storage access even for non-tracking resources, since
+    // we will need the result when computing the access rights for the reject
+    // foreign cookie behavior mode.
+    if (isForeign &&
         AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
                                                                 aHostURI)) {
       firstPartyStorageAccessGranted = true;
     }
   }
 
   bool isSafeTopLevelNav = NS_IsSafeTopLevelNav(aChannel);
   bool isSameSiteForeign = NS_IsSameSiteForeign(aChannel, aHostURI);
@@ -633,17 +639,20 @@ CookieServiceChild::SetCookieStringInter
   if (RequireThirdPartyCheck())
     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
 
   bool isTrackingResource = false;
   bool firstPartyStorageAccessGranted = false;
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   if (httpChannel) {
     isTrackingResource = httpChannel->GetIsTrackingResource();
-    if (isForeign && isTrackingResource &&
+    // Check first-party storage access even for non-tracking resources, since
+    // we will need the result when computing the access rights for the reject
+    // foreign cookie behavior mode.
+    if (isForeign &&
         AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
                                                                 aHostURI)) {
       firstPartyStorageAccessGranted = true;
     }
   }
 
   nsDependentCString cookieString(aCookieString);
   nsDependentCString stringServerTime;
--- a/netwerk/cookie/CookieServiceParent.cpp
+++ b/netwerk/cookie/CookieServiceParent.cpp
@@ -156,17 +156,20 @@ CookieServiceParent::TrackCookieLoad(nsI
   bool isForeign = true;
   thirdPartyUtil->IsThirdPartyChannel(aChannel, uri, &isForeign);
 
   bool isTrackingResource = false;
   bool storageAccessGranted = false;
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   if (httpChannel) {
     isTrackingResource = httpChannel->GetIsTrackingResource();
-    if (isForeign && isTrackingResource &&
+    // Check first-party storage access even for non-tracking resources, since
+    // we will need the result when computing the access rights for the reject
+    // foreign cookie behavior mode.
+    if (isForeign &&
         AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
                                                                 uri)) {
       storageAccessGranted = true;
     }
   }
 
   nsTArray<nsCookie*> foundCookieList;
   mCookieService->GetCookiesForURI(uri, isForeign, isTrackingResource,
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -2040,17 +2040,20 @@ nsCookieService::GetCookieStringCommon(n
   mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
 
   bool isTrackingResource = false;
   bool firstPartyStorageAccessGranted = false;
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   if (httpChannel) {
     isTrackingResource = httpChannel->GetIsTrackingResource();
 
-    if (isForeign && isTrackingResource &&
+    // Check first-party storage access even for non-tracking resources, since
+    // we will need the result when computing the access rights for the reject
+    // foreign cookie behavior mode.
+    if (isForeign &&
         AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
                                                                 aHostURI)) {
       firstPartyStorageAccessGranted = true;
     }
   }
 
   OriginAttributes attrs;
   if (aChannel) {
@@ -2147,17 +2150,20 @@ nsCookieService::SetCookieStringCommon(n
   mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
 
   bool isTrackingResource = false;
   bool firstPartyStorageAccessGranted = false;
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   if (httpChannel) {
     isTrackingResource = httpChannel->GetIsTrackingResource();
 
-    if (isForeign && isTrackingResource &&
+    // Check first-party storage access even for non-tracking resources, since
+    // we will need the result when computing the access rights for the reject
+    // foreign cookie behavior mode.
+    if (isForeign &&
         AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
                                                                 aHostURI)) {
       firstPartyStorageAccessGranted = true;
     }
   }
 
   OriginAttributes attrs;
   if (aChannel) {
@@ -4254,31 +4260,35 @@ nsCookieService::CheckPrefs(nsICookiePer
   // check default prefs
   if (aCookieBehavior == nsICookieService::BEHAVIOR_REJECT) {
     COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "cookies are disabled");
     return STATUS_REJECTED;
   }
 
   // check if cookie is foreign
   if (aIsForeign) {
-    if (aCookieBehavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN) {
+    // Check aFirstPartyStorageAccessGranted when rejecting all third-party cookies,
+    // so that we take things such as the content blocking allow list into account.
+    if (aCookieBehavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN &&
+        !aFirstPartyStorageAccessGranted) {
       COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party");
       return STATUS_REJECTED;
     }
 
     if (aCookieBehavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) {
       if (aNumOfCookies == 0) {
         COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party");
         return STATUS_REJECTED;
       }
     }
 
     MOZ_ASSERT(aCookieBehavior == nsICookieService::BEHAVIOR_ACCEPT ||
                aCookieBehavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN ||
                // But with permission granted.
+               aCookieBehavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
                aCookieBehavior == nsICookieService::BEHAVIOR_REJECT_TRACKER);
 
     if (aThirdPartySession)
       return STATUS_ACCEPT_SESSION;
 
     if (aThirdPartyNonsecureSession) {
       bool isHTTPS = false;
       aHostURI->SchemeIs("https", &isHTTPS);
--- a/toolkit/components/antitracking/AntiTrackingCommon.cpp
+++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp
@@ -368,16 +368,22 @@ AntiTrackingCommon::IsFirstPartyStorageA
   }
 
   // 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 &&
+      CheckContentBlockingAllowList(aWindow)) {
+    LOG(("Allowing access even though our behavior is reject foreign"));
+    return true;
+  }
+
   if (behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
       behavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) {
     // XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
     // 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)));
     return false;
@@ -539,16 +545,22 @@ AntiTrackingCommon::IsFirstPartyStorageA
                                                 nullptr,
                                                 &thirdParty);
   // Grant if it's not a 3rd party.
   if (!thirdParty) {
     LOG(("Our channel isn't a third-party channel"));
     return true;
   }
 
+  if (behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN &&
+      CheckContentBlockingAllowList(aChannel)) {
+    LOG(("Allowing access even though our behavior is reject foreign"));
+    return true;
+  }
+
   if (behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
       behavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) {
     // XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
     // 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)));
     return false;