Bug 1503697 - Record trackers being loaded on a site in the content blocking log; r=baku,francois
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 31 Oct 2018 18:52:37 -0400
changeset 444573 56bb430315885b97469a28aef13c2f48bc6fc276
parent 444572 be98a5ed931b69db01361ca6b7dca785bcfbc503
child 444574 9b4bf02afd60b4bec3e7d2cd8b3179e8b63faa3b
push id34997
push userrgurzau@mozilla.com
push dateTue, 06 Nov 2018 09:59:47 +0000
treeherdermozilla-central@957a743c4ca2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, francois
bugs1503697
milestone65.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 1503697 - Record trackers being loaded on a site in the content blocking log; r=baku,francois Differential Revision: https://phabricator.services.mozilla.com/D10439
dom/base/nsDocument.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsIDocument.h
netwerk/base/nsChannelClassifier.cpp
netwerk/base/nsChannelClassifier.h
toolkit/components/antitracking/test/browser/browser_subResources.js
toolkit/components/antitracking/test/browser/head.js
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1393,17 +1393,16 @@ nsIDocument::nsIDocument()
     mHasMixedActiveContentLoaded(false),
     mHasMixedActiveContentBlocked(false),
     mHasMixedDisplayContentLoaded(false),
     mHasMixedDisplayContentBlocked(false),
     mHasMixedContentObjectSubrequest(false),
     mHasCSP(false),
     mHasUnsafeEvalCSP(false),
     mHasUnsafeInlineCSP(false),
-    mHasTrackingContentLoaded(false),
     mBFCacheDisallowed(false),
     mHasHadDefaultView(false),
     mStyleSheetChangeEventsEnabled(false),
     mIsSrcdocDocument(false),
     mDidDocumentOpen(false),
     mHasDisplayDocument(false),
     mFontFaceSetDirty(true),
     mGetUserFontSetCalled(false),
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -5330,16 +5330,21 @@ nsGlobalWindowOuter::NotifyContentBlocki
   nsContentUtils::GetUTFOrigin(aURIHint, origin);
 
   bool unblocked = false;
   if (aState == nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT) {
     doc->SetHasTrackingContentBlocked(aBlocked, origin);
     if (!aBlocked) {
       unblocked = !doc->GetHasTrackingContentBlocked();
     }
+  } else if (aState == nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT) {
+    doc->SetHasTrackingContentLoaded(aBlocked, origin);
+    if (!aBlocked) {
+      unblocked = !doc->GetHasTrackingContentLoaded();
+    }
   } else if (aState == nsIWebProgressListener::STATE_BLOCKED_SLOW_TRACKING_CONTENT) {
     doc->SetHasSlowTrackingContentBlocked(aBlocked, origin);
     if (!aBlocked) {
       unblocked = !doc->GetHasSlowTrackingContentBlocked();
     }
   } else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION) {
     doc->SetHasCookiesBlockedByPermission(aBlocked, origin);
     if (!aBlocked) {
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1110,25 +1110,29 @@ public:
                              aHasCookiesBlockedByPermission);
   }
 
   /**
    * Get tracking content loaded flag for this document.
    */
   bool GetHasTrackingContentLoaded()
   {
-    return mHasTrackingContentLoaded;
+    return mContentBlockingLog.HasBlockedAnyOfType(
+        nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT);
   }
 
   /**
    * Set the tracking content loaded flag for this document.
    */
-  void SetHasTrackingContentLoaded(bool aHasTrackingContentLoaded)
-  {
-    mHasTrackingContentLoaded = aHasTrackingContentLoaded;
+  void SetHasTrackingContentLoaded(bool aHasTrackingContentLoaded,
+                                   const nsAString& aOriginBlocked)
+  {
+    RecordContentBlockingLog(aOriginBlocked,
+                             nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT,
+                             aHasTrackingContentLoaded);
   }
 
   /**
    * Get the sandbox flags for this document.
    * @see nsSandboxFlags.h for the possible flags
    */
   uint32_t GetSandboxFlags() const
   {
@@ -4208,19 +4212,16 @@ protected:
   bool mHasCSP : 1;
 
   // True if a document load has a CSP with unsafe-eval attached.
   bool mHasUnsafeEvalCSP : 1;
 
   // True if a document load has a CSP with unsafe-inline attached.
   bool mHasUnsafeInlineCSP : 1;
 
-  // True if a document has loaded Tracking Content
-  bool mHasTrackingContentLoaded : 1;
-
   // True if DisallowBFCaching has been called on this document.
   bool mBFCacheDisallowed : 1;
 
   bool mHasHadDefaultView : 1;
 
   // Whether style sheet change events will be dispatched for this document
   bool mStyleSheetChangeEventsEnabled : 1;
 
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -594,50 +594,17 @@ nsChannelClassifier::NotifyTrackingProte
     NS_QueryNotificationCallbacks(aChannel, parentChannel);
     if (parentChannel) {
       // This channel is a parent-process proxy for a child process request.
       // Tell the child process channel to do this instead.
       parentChannel->NotifyTrackingProtectionDisabled();
       return NS_OK;
     }
 
-    nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
-      services::GetThirdPartyUtil();
-    if (NS_WARN_IF(!thirdPartyUtil)) {
-      return NS_ERROR_FAILURE;
-    }
-
-    nsresult rv;
-    nsCOMPtr<mozIDOMWindowProxy> win;
-    rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, getter_AddRefs(win));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    auto* pwin = nsPIDOMWindowOuter::From(win);
-    nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
-    if (!docShell) {
-      return NS_OK;
-    }
-    nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
-    NS_ENSURE_TRUE(doc, NS_OK);
-
-    // Notify nsIWebProgressListeners of this security event.
-    // Can be used to change the UI state.
-    nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell, &rv);
-    NS_ENSURE_SUCCESS(rv, NS_OK);
-    uint32_t state = 0;
-    nsCOMPtr<nsISecureBrowserUI> securityUI;
-    docShell->GetSecurityUI(getter_AddRefs(securityUI));
-    if (!securityUI) {
-      return NS_OK;
-    }
-    doc->SetHasTrackingContentLoaded(true);
-    securityUI->GetState(&state);
-    const uint32_t oldState = state;
-    state |= nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT;
-    eventSink->OnSecurityChange(nullptr, oldState, state, doc->GetContentBlockingLog());
+    NotifyChannelBlocked(aChannel, nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT);
 
     return NS_OK;
 }
 
 void
 nsChannelClassifier::Start()
 {
   nsresult rv = StartInternal();
@@ -918,27 +885,27 @@ nsChannelClassifier::SetBlockedContent(n
   auto* pwin = nsPIDOMWindowOuter::From(win);
   nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
   if (!docShell) {
     return NS_OK;
   }
   nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
   NS_ENSURE_TRUE(doc, NS_OK);
 
-  nsCOMPtr<nsIURI> uri;
-  channel->GetURI(getter_AddRefs(uri));
   unsigned state;
   if (aErrorCode == NS_ERROR_TRACKING_URI) {
     state = nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
   } else {
     state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
   }
-  pwin->NotifyContentBlockingState(state, channel, true, uri);
+  NotifyChannelBlocked(channel, state);
 
   // Log a warning to the web console.
+  nsCOMPtr<nsIURI> uri;
+  channel->GetURI(getter_AddRefs(uri));
   NS_ConvertUTF8toUTF16 spec(uri->GetSpecOrDefault());
   const char16_t* params[] = { spec.get() };
   const char* message = (aErrorCode == NS_ERROR_TRACKING_URI) ?
     "TrackerUriBlocked" : "UnsafeUriBlocked";
   nsCString category = (aErrorCode == NS_ERROR_TRACKING_URI) ?
     NS_LITERAL_CSTRING("Tracking Protection") :
     NS_LITERAL_CSTRING("Safe Browsing");
 
@@ -947,16 +914,42 @@ nsChannelClassifier::SetBlockedContent(n
                                   doc,
                                   nsContentUtils::eNECKO_PROPERTIES,
                                   message,
                                   params, ArrayLength(params));
 
   return NS_OK;
 }
 
+// static
+void
+nsChannelClassifier::NotifyChannelBlocked(nsIChannel* aChannel, unsigned aBlockedReason)
+{
+  nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
+    services::GetThirdPartyUtil();
+  if (NS_WARN_IF(!thirdPartyUtil)) {
+    return;
+  }
+
+  nsCOMPtr<mozIDOMWindowProxy> win;
+  nsresult rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, getter_AddRefs(win));
+  NS_ENSURE_SUCCESS_VOID(rv);
+  auto* pwin = nsPIDOMWindowOuter::From(win);
+  nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
+  if (!docShell) {
+    return;
+  }
+  nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
+  NS_ENSURE_TRUE_VOID(doc);
+
+  nsCOMPtr<nsIURI> uri;
+  aChannel->GetURI(getter_AddRefs(uri));
+  pwin->NotifyContentBlockingState(aBlockedReason, aChannel, true, uri);
+}
+
 namespace {
 
 // This class is designed to get the results of checking blacklist and whitelist.
 // |mExpect*WhitelistResult| are used to indicate that |OnClassifyComplete| is called
 // for the result of blacklist or whitelist check.
 class TrackingURICallback final : public nsIURIClassifierCallback {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
--- a/netwerk/base/nsChannelClassifier.h
+++ b/netwerk/base/nsChannelClassifier.h
@@ -90,16 +90,18 @@ private:
 
     bool AddonMayLoad(nsIChannel *aChannel, nsIURI *aUri);
     void AddShutdownObserver();
     void RemoveShutdownObserver();
     static nsresult SendThreatHitReport(nsIChannel *aChannel,
                                         const nsACString& aProvider,
                                         const nsACString& aList,
                                         const nsACString& aFullHash);
+
+    static void NotifyChannelBlocked(nsIChannel* aChannel, unsigned aBlockedReason);
 public:
     // If we are blocking content, update the corresponding flag in the respective
     // docshell and call nsISecurityEventSink::onSecurityChange.
     static nsresult SetBlockedContent(nsIChannel *channel,
                                       nsresult aErrorCode,
                                       const nsACString& aList,
                                       const nsACString& aProvider,
                                       const nsACString& aFullHash);
--- a/toolkit/components/antitracking/test/browser/browser_subResources.js
+++ b/toolkit/components/antitracking/test/browser/browser_subResources.js
@@ -151,33 +151,65 @@ add_task(async function() {
     });
 
   await fetch("https://tracking.example.org/browser/toolkit/components/antitracking/test/browser/subResources.sjs?result&what=script")
     .then(r => r.text())
     .then(text => {
       is(text, 1, "One cookie received received for scripts.");
     });
 
+  let expectTrackerFound = item => {
+    is(item[0], Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT,
+       "Correct blocking type reported");
+    is(item[1], true,
+       "Correct blocking status reported");
+    ok(item[2] >= 1,
+       "Correct repeat count reported");
+  };
+
   let log = JSON.parse(await browser.getContentBlockingLog());
   for (let trackerOrigin in log) {
     is(trackerOrigin, TEST_3RD_PARTY_DOMAIN, "Correct tracker origin must be reported");
     let originLog = log[trackerOrigin];
-    is(originLog.length, 2, "We should have two entries in the compressed log");
-    is(originLog[0][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
-       "Correct blocking type reported");
-    is(originLog[0][1], true,
-       "Correct blocking status reported");
-    is(originLog[0][2], 6, // 1 for each HTTP request which attempts to set a cookie
-       "Correct repeat count reported");
+    is(originLog.length, 10, "We should have 10 entries in the compressed log");
+    expectTrackerFound(originLog[0]);
     is(originLog[1][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
        "Correct blocking type reported");
-    is(originLog[1][1], false,
+    is(originLog[1][1], true,
+       "Correct blocking status reported");
+    is(originLog[1][2], 1,
+       "Correct repeat count reported");
+    expectTrackerFound(originLog[2]);
+    is(originLog[3][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
+       "Correct blocking type reported");
+    is(originLog[3][1], true,
+       "Correct blocking status reported");
+    is(originLog[3][2], 1,
+       "Correct repeat count reported");
+    expectTrackerFound(originLog[4]);
+    is(originLog[5][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
+       "Correct blocking type reported");
+    is(originLog[5][1], true,
        "Correct blocking status reported");
-    is(originLog[1][2], 1, // Only got unblocked once
+    is(originLog[5][2], 1,
        "Correct repeat count reported");
+    expectTrackerFound(originLog[6]);
+    is(originLog[7][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
+       "Correct blocking type reported");
+    is(originLog[7][1], true,
+       "Correct blocking status reported");
+    is(originLog[7][2], 3,
+       "Correct repeat count reported");
+    is(originLog[8][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
+       "Correct blocking type reported");
+    is(originLog[8][1], false,
+       "Correct blocking status reported");
+    is(originLog[8][2], 1,
+       "Correct repeat count reported");
+    expectTrackerFound(originLog[9]);
   }
 
   info("Removing the tab");
   BrowserTestUtils.removeTab(tab);
 });
 
 add_task(async function() {
   info("Cleaning up.");
--- a/toolkit/components/antitracking/test/browser/head.js
+++ b/toolkit/components/antitracking/test/browser/head.js
@@ -296,51 +296,66 @@ this.AntiTracking = {
               is(oldState & options.expectedBlockingNotifications, 0,
                  "When blocking the first cookie, old state should not have had " +
                  "one of the blocking flag bit");
             }
 
             for (let trackerOrigin in contentBlockingLog) {
               is(trackerOrigin, TEST_3RD_PARTY_DOMAIN, "Correct tracker origin must be reported");
               let originLog = contentBlockingLog[trackerOrigin];
-              if (originLog.length == 1) {
-                is(originLog[0][0], options.expectedBlockingNotifications,
-                   "Correct blocking type reported");
-                is(originLog[0][1], true,
-                   "Correct blocking status reported");
-                ok(originLog[0][2] >= 1,
-                   "Correct repeat count reported");
-              } else {
-                // This branch is needed here because of the tests that use the storage
-                // access API to gain storage access.
-                is(originLog.length, 2, "Correct origin log length");
-                is(originLog[0][0], options.expectedBlockingNotifications,
-                   "Correct blocking type reported");
-                is(originLog[0][1], true,
-                   "Correct blocking status reported");
-                ok(originLog[0][2] >= 1,
-                   "Correct repeat count reported");
-                is(originLog[1][0], options.expectedBlockingNotifications,
-                   "Correct blocking type reported");
-                is(originLog[1][1], false,
-                   "Correct blocking status reported");
-                is(originLog[1][2], 1,
-                   "Correct repeat count reported");
+              if (options.expectedBlockingNotifications != Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_BY_PERMISSION)
+              ok(originLog.length > 1, "We should have at least two items in the log");
+              for (let i = 0; i < originLog.length; ++i) {
+                let item = originLog[i];
+                switch (item[0]) {
+                case Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT:
+                  is(item[1], true, "Correct blocking status reported");
+                  is(item[2], 1, "Correct repeat count reported");
+                  break;
+                case Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT:
+                  if (item[1]) {
+                    ok(item[2] >= 1, "Correct repeat count reported");
+                  } else {
+                    // This branch is needed here because of the tests that use the storage
+                    // access API to gain storage access.
+                    is(item[2], 1, "Correct repeat count reported");
+                  }
+                  break;
+                case Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER:
+                  if (item[1]) {
+                    ok(item[2] >= 1, "Correct repeat count reported");
+                  } else {
+                    // This branch is needed here because of the tests that use the storage
+                    // access API to gain storage access.
+                    is(item[2], 1, "Correct repeat count reported");
+                  }
+                  break;
+                }
               }
             }
             // Can't assert the number of tracker origins because we may get 0
             // for web progress navigations coming from the window opening from
             // storage access API tracker interaction attempts...
           }
           if (!options.expectedBlockingNotifications) {
             is(oldState & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, 0,
                "When not blocking, old state should not have had the " +
                "STATE_COOKIES_BLOCKED_TRACKER bit");
-            is(Object.keys(contentBlockingLog).length, 0,
-               "Content blocking log JSON must be empty");
+            // Ensure that if there is something in the content blocking log, it's only
+            // STATE_LOADED_TRACKING_CONTENT notifications.
+            for (let trackerOrigin in contentBlockingLog) {
+              let originLog = contentBlockingLog[trackerOrigin];
+              for (let i = 0; i < originLog.length; ++i) {
+                let item = originLog[i];
+                is(item[0], Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT,
+                   "Correct blocking type must be reported");
+                is(item[1], true, "Correct blocking status reported");
+                ok(item[2] >= 1, "Correct repeat count reported");
+              }
+            }
           }
         },
       };
       win.gBrowser.addProgressListener(listener);
 
       info("Creating a new tab");
       let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_TOP_PAGE);
       win.gBrowser.selectedTab = tab;
@@ -515,37 +530,39 @@ this.AntiTracking = {
               is(oldState & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, 0,
                  "When blocking the first cookie, old state should not have had the " +
                  "STATE_COOKIES_BLOCKED_TRACKER bit");
             }
 
             for (let trackerOrigin in contentBlockingLog) {
               is(trackerOrigin, TEST_3RD_PARTY_DOMAIN, "Correct tracker origin must be reported");
               let originLog = contentBlockingLog[trackerOrigin];
-              if (originLog.length == 1) {
-                is(originLog[0][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
-                   "Correct blocking type reported");
-                is(originLog[0][1], true,
-                   "Correct blocking status reported");
-                ok(originLog[0][2] >= 1,
-                   "Correct repeat count reported");
-              } else {
-                is(originLog.length, 2, "Correct origin log length");
-                is(originLog[0][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
-                   "Correct blocking type reported");
-                is(originLog[0][1], true,
-                   "Correct blocking status reported");
-                ok(originLog[0][2] >= 1,
-                   "Correct repeat count reported");
-                is(originLog[1][0], Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER,
-                   "Correct blocking type reported");
-                is(originLog[1][1], false,
-                   "Correct blocking status reported");
-                is(originLog[1][2], 1,
-                   "Correct repeat count reported");
+              ok(originLog.length > 1, "We should have at least two items in the log");
+              for (let i = 0; i < originLog.length; ++i) {
+                let item = originLog[i];
+                switch (item[0]) {
+                case Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT:
+                  is(item[1], true, "Correct blocking status reported");
+                  ok(item[2] >= 1, "Correct repeat count reported");
+                  break;
+                case Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT:
+                  if (item[1]) {
+                    ok(item[2] >= 1, "Correct repeat count reported");
+                  } else {
+                    is(item[2], 1, "Correct repeat count reported");
+                  }
+                  break;
+                case Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER:
+                  if (item[1]) {
+                    ok(item[2] >= 1, "Correct repeat count reported");
+                  } else {
+                    is(item[2], 1, "Correct repeat count reported");
+                  }
+                  break;
+                }
               }
             }
             // Can't assert the number of tracker origins because we may get 0
             // for web progress navigations coming from the window opening...
           }
         },
       };
       win.gBrowser.addProgressListener(listener);
@@ -650,37 +667,39 @@ this.AntiTracking = {
               is(oldState & expectedBlockingNotifications, 0,
                  "When blocking the first cookie, old state should not have had " +
                  "one of the blocking flag bit");
             }
 
             for (let trackerOrigin in contentBlockingLog) {
               is(trackerOrigin, TEST_3RD_PARTY_DOMAIN, "Correct tracker origin must be reported");
               let originLog = contentBlockingLog[trackerOrigin];
-              if (originLog.length == 1) {
-                is(originLog[0][0], expectedBlockingNotifications,
-                   "Correct blocking type reported");
-                is(originLog[0][1], true,
-                   "Correct blocking status reported");
-                ok(originLog[0][2] >= 1,
-                   "Correct repeat count reported");
-              } else {
-                is(originLog.length, 2, "Correct origin log length");
-                is(originLog[0][0], expectedBlockingNotifications,
-                   "Correct blocking type reported");
-                is(originLog[0][1], true,
-                   "Correct blocking status reported");
-                ok(originLog[0][2] >= 1,
-                   "Correct repeat count reported");
-                is(originLog[1][0], expectedBlockingNotifications,
-                   "Correct blocking type reported");
-                is(originLog[1][1], false,
-                   "Correct blocking status reported");
-                ok(originLog[1][2] >= 1,
-                   "Correct repeat count reported");
+              ok(originLog.length > 1, "We should have at least two items in the log");
+              for (let i = 0; i < originLog.length; ++i) {
+                let item = originLog[i];
+                switch (item[0]) {
+                case Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT:
+                  is(item[1], true, "Correct blocking status reported");
+                  ok(item[2] >= 1, "Correct repeat count reported");
+                  break;
+                case Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT:
+                  if (item[1]) {
+                    ok(item[2] >= 1, "Correct repeat count reported");
+                  } else {
+                    // This branch is needed here because of the tests that use the storage
+                    // access API to gain storage access.
+                    is(item[2], 1, "Correct repeat count reported");
+                  }
+                  break;
+                case Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER:
+                  // We can expect 1 or more repeat count whether or not blocking has happened,
+                  // so nothing to assert on item[1].
+                  ok(item[2] >= 1, "Correct repeat count reported");
+                  break;
+                }
               }
             }
             // Can't assert the number of tracker origins because we may get 0
             // for web progress navigations coming from the window opening...
           }
         },
       };
       win.gBrowser.addProgressListener(listener);