Bug 1486185 - Part 1: Make the Disable Protection button in the control centre UI work for the reject tracker cookie behavior; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 25 Aug 2018 01:58:00 -0400
changeset 433573 27b7d1d053fb992fdc742aaa15b2395cf12ed211
parent 433572 ea6c1463602cb9f7bad261326b7a0041b12a5dda
child 433574 8e9cb8f36114e0d2c2b7594d4d124784b6d41483
push id34518
push useraciure@mozilla.com
push dateTue, 28 Aug 2018 21:58:56 +0000
treeherdermozilla-central@3205543f957c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1486185
milestone63.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 1486185 - Part 1: Make the Disable Protection button in the control centre UI work for the reject tracker cookie behavior; r=baku
extensions/cookie/nsPermissionManager.cpp
toolkit/components/antitracking/AntiTrackingCommon.cpp
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -130,17 +130,19 @@ static const char* kPreloadPermissions[]
   "image",
   "manifest",
   "speculative",
 
   // This permission is preloaded to support properly blocking service worker
   // interception when a user has disabled storage for a specific site.  Once
   // service worker interception moves to the parent process this should be
   // removed.  See bug 1428130.
-  "cookie"
+  "cookie",
+  "trackingprotection",
+  "trackingprotection-pb"
 };
 
 // A list of permissions that can have a fallback default permission
 // set under the permissions.default.* pref.
 static const char* kPermissionsWithDefaults[] = {
   "camera",
   "microphone",
   "geo",
--- a/toolkit/components/antitracking/AntiTrackingCommon.cpp
+++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp
@@ -4,23 +4,25 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AntiTrackingCommon.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/AbstractThread.h"
+#include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Logging.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindowInner.h"
 #include "nsICookiePermission.h"
 #include "nsICookieService.h"
+#include "nsIHttpChannelInternal.h"
 #include "nsIIOService.h"
 #include "nsIPermissionManager.h"
 #include "nsIPrincipal.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsPIDOMWindow.h"
 #include "nsScriptSecurityManager.h"
 #include "prtime.h"
@@ -127,16 +129,65 @@ CookiesBehavior(nsIPrincipal* aPrincipal
   // (See Bug 1406675 for rationale).
   if (BasePrincipal::Cast(aPrincipal)->AddonPolicy()) {
     return nsICookieService::BEHAVIOR_ACCEPT;
   }
 
   return StaticPrefs::network_cookie_cookieBehavior();
 }
 
+bool
+CheckContentBlockingAllowList(nsIURI* aTopWinURI)
+{
+  bool isAllowed = false;
+  nsresult rv =
+    AntiTrackingCommon::IsOnContentBlockingAllowList(aTopWinURI, isAllowed);
+  if (NS_SUCCEEDED(rv) && isAllowed) {
+    LOG_SPEC(("The top-level window (%s) is on the content blocking allow list, "
+              "bail out early", _spec), aTopWinURI);
+    return true;
+  }
+  if (NS_FAILED(rv)) {
+    LOG_SPEC(("Checking the content blocking allow list for %s failed with %" PRIx32,
+              _spec, static_cast<uint32_t>(rv)), aTopWinURI);
+  }
+  return false;
+}
+
+bool
+CheckContentBlockingAllowList(nsPIDOMWindowInner* aWindow)
+{
+  nsPIDOMWindowOuter* top = aWindow->GetScriptableTop();
+  if (top) {
+    nsIURI* topWinURI = top->GetDocumentURI();
+    return CheckContentBlockingAllowList(topWinURI);
+  }
+
+  LOG(("Could not check the content blocking allow list because the top "
+       "window wasn't accessible"));
+  return false;
+}
+
+bool
+CheckContentBlockingAllowList(nsIHttpChannel* aChannel)
+{
+  nsCOMPtr<nsIHttpChannelInternal> chan = do_QueryInterface(aChannel);
+  if (chan) {
+    nsCOMPtr<nsIURI> topWinURI;
+    nsresult rv = chan->GetTopWindowURI(getter_AddRefs(topWinURI));
+    if (NS_SUCCEEDED(rv)) {
+      return CheckContentBlockingAllowList(topWinURI);
+    }
+  }
+
+  LOG(("Could not check the content blocking allow list because the top "
+       "window wasn't accessible"));
+  return false;
+}
+
 } // anonymous
 
 /* static */ RefPtr<AntiTrackingCommon::StorageAccessGrantPromise>
 AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigin,
                                                          nsPIDOMWindowInner* aParentWindow)
 {
   MOZ_ASSERT(aParentWindow);
 
@@ -150,16 +201,20 @@ AntiTrackingCommon::AddFirstPartyStorage
     return StorageAccessGrantPromise::CreateAndResolve(true, __func__);
   }
 
   if (!StaticPrefs::browser_contentblocking_enabled()) {
     LOG(("The content blocking pref has been disabled, bail out early"));
     return StorageAccessGrantPromise::CreateAndResolve(true, __func__);
   }
 
+  if (CheckContentBlockingAllowList(aParentWindow)) {
+    return StorageAccessGrantPromise::CreateAndResolve(true, __func__);
+  }
+
   nsCOMPtr<nsIPrincipal> topLevelStoragePrincipal;
   nsAutoCString trackingOrigin;
 
   nsGlobalWindowInner* parentWindow = nsGlobalWindowInner::Cast(aParentWindow);
   nsGlobalWindowOuter* outerParentWindow =
     nsGlobalWindowOuter::Cast(parentWindow->GetOuterWindow());
   if (NS_WARN_IF(!outerParentWindow)) {
     LOG(("No outer window found for our parent window, bailing out early"));
@@ -332,16 +387,20 @@ AntiTrackingCommon::IsFirstPartyStorageA
 
   // Now, we have to also honour the Content Blocking pref.
   if (!StaticPrefs::browser_contentblocking_enabled()) {
     LOG(("The content blocking pref has been disabled, bail out early by "
          "by pretending our window isn't a tracking window"));
     return true;
   }
 
+  if (CheckContentBlockingAllowList(aWindow)) {
+    return true;
+  }
+
   if (!nsContentUtils::IsTrackingResourceWindow(aWindow)) {
     LOG(("Our window isn't a tracking window"));
     return true;
   }
 
   nsCOMPtr<nsIPrincipal> parentPrincipal;
   nsAutoCString trackingOrigin;
   if (!GetParentPrincipalAndTrackingOrigin(nsGlobalWindowInner::Cast(aWindow),
@@ -499,16 +558,20 @@ AntiTrackingCommon::IsFirstPartyStorageA
 
   // Now, we have to also honour the Content Blocking pref.
   if (!StaticPrefs::browser_contentblocking_enabled()) {
     LOG(("The content blocking pref has been disabled, bail out early by "
          "pretending our channel isn't a tracking channel"));
     return true;
   }
 
+  if (CheckContentBlockingAllowList(aChannel)) {
+    return true;
+  }
+
   nsIPrincipal* parentPrincipal = loadInfo->TopLevelStorageAreaPrincipal();
   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.
     if (loadInfo->TopLevelPrincipal()) {
       LOG(("Parent window is the top-level window, bail out early"));
@@ -612,16 +675,20 @@ AntiTrackingCommon::MaybeIsFirstPartySto
   }
 
   // Now, we have to also honour the Content Blocking pref.
   if (!StaticPrefs::browser_contentblocking_enabled()) {
     LOG(("The content blocking pref has been disabled, bail out early"));
     return true;
   }
 
+  if (CheckContentBlockingAllowList(aFirstPartyWindow)) {
+    return true;
+  }
+
   if (!nsContentUtils::IsThirdPartyWindowOrChannel(aFirstPartyWindow,
                                                    nullptr, aURI)) {
     LOG(("Our window isn't a third-party window"));
     return true;
   }
 
   nsCOMPtr<nsIPrincipal> parentPrincipal =
     nsGlobalWindowInner::Cast(aFirstPartyWindow)->GetPrincipal();