Bug 1533074 - Implement Fingerprinting and Cryptomining annotation features - Part 1 - Classification flags in nsIHttpChannel, r=valentin,dimi
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 14 Mar 2019 17:47:59 +0000
changeset 521915 a0c8d47ee188ee72fb0896dd80b02076f9bcafb5
parent 521914 45024ae5b1b7a079cfa1913b63dd15c7ba050d87
child 521916 83534ac4c0eb43b8cfa1c6f93431978fe11ba120
push id10870
push usernbeleuzu@mozilla.com
push dateFri, 15 Mar 2019 20:00:07 +0000
treeherdermozilla-beta@c594aee5b7a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin, dimi
bugs1533074
milestone67.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 1533074 - Implement Fingerprinting and Cryptomining annotation features - Part 1 - Classification flags in nsIHttpChannel, r=valentin,dimi Differential Revision: https://phabricator.services.mozilla.com/D22341
netwerk/base/SimpleChannelParent.cpp
netwerk/base/nsIParentChannel.idl
netwerk/cookie/CookieServiceParent.h
netwerk/protocol/data/DataChannelParent.cpp
netwerk/protocol/file/FileChannelParent.cpp
netwerk/protocol/ftp/FTPChannelParent.cpp
netwerk/protocol/http/HttpBackgroundChannelChild.cpp
netwerk/protocol/http/HttpBackgroundChannelChild.h
netwerk/protocol/http/HttpBackgroundChannelParent.cpp
netwerk/protocol/http/HttpBackgroundChannelParent.h
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/NullHttpChannel.cpp
netwerk/protocol/http/PHttpBackgroundChannel.ipdl
netwerk/protocol/http/PTrackingDummyChannel.ipdl
netwerk/protocol/http/TrackingDummyChannel.cpp
netwerk/protocol/http/TrackingDummyChannel.h
netwerk/protocol/http/TrackingDummyChannelChild.cpp
netwerk/protocol/http/TrackingDummyChannelChild.h
netwerk/protocol/http/TrackingDummyChannelParent.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsIHttpChannel.idl
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp
uriloader/exthandler/nsExternalProtocolHandler.cpp
--- a/netwerk/base/SimpleChannelParent.cpp
+++ b/netwerk/base/SimpleChannelParent.cpp
@@ -43,17 +43,18 @@ SimpleChannelParent::NotifyCookieAllowed
 
 NS_IMETHODIMP
 SimpleChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
   // Nothing to do.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SimpleChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
+SimpleChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
+                                               bool aIsThirdParty) {
   // Nothing to do.
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SimpleChannelParent::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   // Nothing to do.
--- a/netwerk/base/nsIParentChannel.idl
+++ b/netwerk/base/nsIParentChannel.idl
@@ -62,20 +62,23 @@ interface nsIParentChannel : nsIStreamLi
    *        String represents full hash that matched
    */
   [noscript] void setClassifierMatchedInfo(in ACString aList,
                                            in ACString aProvider,
                                            in ACString aFullHash);
 
   /**
    * Called to notify the HttpChannelChild that the resource being loaded
-   * is on the tracking protection list.
+   * has been classified.
+   * @param aClassificationFlags
+   *        What classifier identifies this channel.
    * @param aIsThirdParty
    *        Whether or not the resourced is considered first-party
    *        with the URI of the window.
    */
-  [noscript] void notifyTrackingResource(in bool aIsThirdParty);
+  [noscript] void notifyClassificationFlags(in uint32_t aClassificationFlags,
+                                            in bool aIsThirdParty);
 
   /**
    * Called to invoke deletion of the IPC protocol.
    */
   void delete();
 };
--- a/netwerk/cookie/CookieServiceParent.h
+++ b/netwerk/cookie/CookieServiceParent.h
@@ -49,17 +49,17 @@ class CookieServiceParent : public PCook
       const Maybe<LoadInfoArgs> &aLoadInfoArgs, const bool &aIsForeign,
       const bool &aIsTrackingResource,
       const bool &aFirstPartyStorageAccessGranted,
       const nsCString &aCookieString, const nsCString &aServerTime,
       const bool &aFromHttp);
 
   mozilla::ipc::IPCResult RecvPrepareCookieList(
       const URIParams &aHost, const bool &aIsForeign,
-      const bool &aIsTackingResource,
+      const bool &aIsTrackingResource,
       const bool &aFirstPartyStorageAccessGranted,
       const bool &aIsSafeTopLevelNav, const bool &aIsSameSiteForeign,
       const OriginAttributes &aAttrs);
 
   void SerialializeCookieList(const nsTArray<nsCookie *> &aFoundCookieList,
                               nsTArray<CookieStruct> &aCookiesList,
                               nsIURI *aHostURI);
 
--- a/netwerk/protocol/data/DataChannelParent.cpp
+++ b/netwerk/protocol/data/DataChannelParent.cpp
@@ -43,17 +43,18 @@ DataChannelParent::NotifyCookieAllowed()
 
 NS_IMETHODIMP
 DataChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
   // Nothing to do.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-DataChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
+DataChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
+                                             bool aIsThirdParty) {
   // Nothing to do.
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DataChannelParent::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   // Nothing to do.
--- a/netwerk/protocol/file/FileChannelParent.cpp
+++ b/netwerk/protocol/file/FileChannelParent.cpp
@@ -43,17 +43,18 @@ FileChannelParent::NotifyCookieAllowed()
 
 NS_IMETHODIMP
 FileChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
   // Nothing to do.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FileChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
+FileChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
+                                             bool aIsThirdParty) {
   // Nothing to do.
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FileChannelParent::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   // Nothing to do.
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
+++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
@@ -510,17 +510,18 @@ FTPChannelParent::NotifyCookieAllowed() 
 
 NS_IMETHODIMP
 FTPChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
   // One day, this should probably be filled in.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FTPChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
+FTPChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
+                                            bool aIsThirdParty) {
   // One day, this should probably be filled in.
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelParent::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   // One day, this should probably be filled in.
--- a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
@@ -339,31 +339,32 @@ IPCResult HttpBackgroundChannelChild::Re
     return IPC_OK();
   }
 
   mChannelChild->ProcessNotifyCookieBlocked(aRejectedReason);
 
   return IPC_OK();
 }
 
-IPCResult HttpBackgroundChannelChild::RecvNotifyTrackingResource(
-    const bool& aIsThirdParty) {
+IPCResult HttpBackgroundChannelChild::RecvNotifyClassificationFlags(
+    const uint32_t& aClassificationFlags, const bool& aIsThirdParty) {
   LOG(
-      ("HttpBackgroundChannelChild::RecvNotifyTrackingResource thirdparty=%d "
-       "[this=%p]\n",
-       static_cast<int>(aIsThirdParty), this));
+      ("HttpBackgroundChannelChild::RecvNotifyClassificationFlags "
+       "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n",
+       aClassificationFlags, static_cast<int>(aIsThirdParty), this));
   MOZ_ASSERT(OnSocketThread());
 
   if (NS_WARN_IF(!mChannelChild)) {
     return IPC_OK();
   }
 
-  // NotifyTrackingResource has no order dependency to OnStartRequest.
+  // NotifyClassificationFlags has no order dependency to OnStartRequest.
   // It this be handled as soon as possible
-  mChannelChild->ProcessNotifyTrackingResource(aIsThirdParty);
+  mChannelChild->ProcessNotifyClassificationFlags(aClassificationFlags,
+                                                  aIsThirdParty);
 
   return IPC_OK();
 }
 
 IPCResult HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged(
     const nsIHttpChannel::FlashPluginState& aState) {
   LOG(
       ("HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged "
--- a/netwerk/protocol/http/HttpBackgroundChannelChild.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.h
@@ -66,17 +66,18 @@ class HttpBackgroundChannelChild final :
 
   IPCResult RecvNotifyChannelClassifierProtectionDisabled(
       const uint32_t& aAcceptedReason);
 
   IPCResult RecvNotifyCookieAllowed();
 
   IPCResult RecvNotifyCookieBlocked(const uint32_t& aRejectedReason);
 
-  IPCResult RecvNotifyTrackingResource(const bool& aIsThirdParty);
+  IPCResult RecvNotifyClassificationFlags(const uint32_t& aClassificationFlags,
+                                          const bool& aIsThirdParty);
 
   IPCResult RecvNotifyFlashPluginStateChanged(
       const nsIHttpChannel::FlashPluginState& aState);
 
   IPCResult RecvSetClassifierMatchedInfo(const ClassifierInfo& info);
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
@@ -400,42 +400,43 @@ bool HttpBackgroundChannelParent::OnNoti
     MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
 
     return NS_SUCCEEDED(rv);
   }
 
   return SendNotifyCookieBlocked(aRejectedReason);
 }
 
-bool HttpBackgroundChannelParent::OnNotifyTrackingResource(bool aIsThirdParty) {
+bool HttpBackgroundChannelParent::OnNotifyClassificationFlags(
+    uint32_t aClassificationFlags, bool aIsThirdParty) {
   LOG(
-      ("HttpBackgroundChannelParent::OnNotifyTrackingResource thirdparty=%d "
-       "[this=%p]\n",
-       static_cast<int>(aIsThirdParty), this));
+      ("HttpBackgroundChannelParent::OnNotifyClassificationFlags "
+       "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n",
+       aClassificationFlags, static_cast<int>(aIsThirdParty), this));
   AssertIsInMainProcess();
 
   if (NS_WARN_IF(!mIPCOpened)) {
     return false;
   }
 
   if (!IsOnBackgroundThread()) {
     MutexAutoLock lock(mBgThreadMutex);
     nsresult rv = mBackgroundThread->Dispatch(
-        NewRunnableMethod<bool>(
-            "net::HttpBackgroundChannelParent::OnNotifyTrackingResource", this,
-            &HttpBackgroundChannelParent::OnNotifyTrackingResource,
-            aIsThirdParty),
+        NewRunnableMethod<uint32_t, bool>(
+            "net::HttpBackgroundChannelParent::OnNotifyClassificationFlags",
+            this, &HttpBackgroundChannelParent::OnNotifyClassificationFlags,
+            aClassificationFlags, aIsThirdParty),
         NS_DISPATCH_NORMAL);
 
     MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
 
     return NS_SUCCEEDED(rv);
   }
 
-  return SendNotifyTrackingResource(aIsThirdParty);
+  return SendNotifyClassificationFlags(aClassificationFlags, aIsThirdParty);
 }
 
 bool HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   LOG(
       ("HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged "
        "[this=%p]\n",
        this));
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.h
@@ -68,18 +68,19 @@ class HttpBackgroundChannelParent final 
   bool OnNotifyChannelClassifierProtectionDisabled(uint32_t aAcceptedReason);
 
   // To send NotifyCookieAllowed message over background channel.
   bool OnNotifyCookieAllowed();
 
   // To send NotifyCookieBlocked message over background channel.
   bool OnNotifyCookieBlocked(uint32_t aRejectedReason);
 
-  // To send NotifyTrackingResource message over background channel.
-  bool OnNotifyTrackingResource(bool aIsThirdParty);
+  // To send NotifyClassificationFlags message over background channel.
+  bool OnNotifyClassificationFlags(uint32_t aClassificationFlags,
+                                   bool aIsThirdParty);
 
   // To send NotifyFlashPluginStateChanged message over background channel.
   bool OnNotifyFlashPluginStateChanged(nsIHttpChannel::FlashPluginState aState);
 
   // To send SetClassifierMatchedInfo message over background channel.
   bool OnSetClassifierMatchedInfo(const nsACString& aList,
                                   const nsACString& aProvider,
                                   const nsACString& aFullHash);
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -163,18 +163,18 @@ HttpBaseChannel::HttpBaseChannel()
       mRequestContextID(0),
       mContentWindowId(0),
       mTopLevelOuterContentWindowId(0),
       mAltDataLength(0),
       mChannelId(0),
       mReqContentLength(0U),
       mStatus(NS_OK),
       mCanceled(false),
-      mIsFirstPartyTrackingResource(false),
-      mIsThirdPartyTrackingResource(false),
+      mFirstPartyClassificationFlags(0),
+      mThirdPartyClassificationFlags(0),
       mFlashPluginState(nsIHttpChannel::FlashPluginUnknown),
       mLoadFlags(LOAD_NORMAL),
       mCaps(0),
       mClassOfService(0),
       mUpgradeToSecure(false),
       mApplyConversion(true),
       mIsPending(false),
       mWasOpened(false),
@@ -303,26 +303,27 @@ void HttpBaseChannel::ReleaseMainThreadO
 
     nsCOMPtr<nsISupports> nonTailRemover(new NonTailRemover(mRequestContext));
     arrayToRelease.AppendElement(nonTailRemover.forget());
   }
 
   NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease)));
 }
 
-void HttpBaseChannel::SetIsTrackingResource(bool aIsThirdParty) {
-  LOG(("HttpBaseChannel::SetIsTrackingResource thirdparty=%d %p",
-       static_cast<int>(aIsThirdParty), this));
+void HttpBaseChannel::AddClassificationFlags(uint32_t aClassificationFlags,
+                                             bool aIsThirdParty) {
+  LOG(
+      ("HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
+       "thirdparty=%d %p",
+       aClassificationFlags, static_cast<int>(aIsThirdParty), this));
 
   if (aIsThirdParty) {
-    MOZ_ASSERT(!mIsFirstPartyTrackingResource);
-    mIsThirdPartyTrackingResource = true;
+    mThirdPartyClassificationFlags |= aClassificationFlags;
   } else {
-    MOZ_ASSERT(!mIsThirdPartyTrackingResource);
-    mIsFirstPartyTrackingResource = true;
+    mFirstPartyClassificationFlags |= aClassificationFlags;
   }
 }
 
 void HttpBaseChannel::SetFlashPluginState(
     nsIHttpChannel::FlashPluginState aState) {
   LOG(("HttpBaseChannel::SetFlashPluginState %p", this));
   mFlashPluginState = aState;
 }
@@ -1464,58 +1465,97 @@ NS_IMETHODIMP HttpBaseChannel::GetTopLev
   return NS_OK;
 }
 
 NS_IMETHODIMP HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId) {
   mContentWindowId = aWindowId;
   return NS_OK;
 }
 
+bool
+HttpBaseChannel::IsTrackingResource() const {
+  MOZ_ASSERT(!mFirstPartyClassificationFlags ||
+             !mThirdPartyClassificationFlags);
+  return
+      (mThirdPartyClassificationFlags & nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING) ||
+      (mFirstPartyClassificationFlags & nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING);
+}
+
 NS_IMETHODIMP
 HttpBaseChannel::GetIsTrackingResource(bool* aIsTrackingResource) {
-  MOZ_ASSERT(!(mIsFirstPartyTrackingResource && mIsThirdPartyTrackingResource));
-  *aIsTrackingResource =
-      mIsThirdPartyTrackingResource || mIsFirstPartyTrackingResource;
+  *aIsTrackingResource = IsTrackingResource();
+  return NS_OK;
+}
+
+bool
+HttpBaseChannel::IsThirdPartyTrackingResource() const {
+  MOZ_ASSERT(
+      !(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags));
+  return (mThirdPartyClassificationFlags & nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING);
+}
+
+NS_IMETHODIMP
+HttpBaseChannel::GetIsThirdPartyTrackingResource(bool* aIsTrackingResource) {
+  *aIsTrackingResource = IsThirdPartyTrackingResource();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HttpBaseChannel::GetIsThirdPartyTrackingResource(bool* aIsTrackingResource) {
-  MOZ_ASSERT(!(mIsFirstPartyTrackingResource && mIsThirdPartyTrackingResource));
-  *aIsTrackingResource = mIsThirdPartyTrackingResource;
+HttpBaseChannel::GetClassificationFlags(uint32_t* aFlags) {
+  MOZ_ASSERT(!mFirstPartyClassificationFlags ||
+             !mThirdPartyClassificationFlags);
+  if (mThirdPartyClassificationFlags) {
+    *aFlags = mThirdPartyClassificationFlags;
+  } else {
+    *aFlags = mFirstPartyClassificationFlags;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HttpBaseChannel::GetFirstPartyClassificationFlags(uint32_t* aFlags) {
+  MOZ_ASSERT(
+      !(mFirstPartyClassificationFlags && mFirstPartyClassificationFlags));
+  *aFlags = mFirstPartyClassificationFlags;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HttpBaseChannel::GetThirdPartyClassificationFlags(uint32_t* aFlags) {
+  MOZ_ASSERT(
+      !(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags));
+  *aFlags = mThirdPartyClassificationFlags;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetFlashPluginState(nsIHttpChannel::FlashPluginState* aState) {
   uint32_t flashPluginState = mFlashPluginState;
   *aState = (nsIHttpChannel::FlashPluginState)flashPluginState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::OverrideTrackingFlagsForDocumentCookieAccessor(
     nsIHttpChannel* aDocumentChannel) {
-  LOG(
-      ("HttpBaseChannel::OverrideTrackingFlagsForDocumentCookieAccessor() %p "
-       "mIsFirstPartyTrackingResource=%d  mIsThirdPartyTrackingResource=%d",
-       this, static_cast<int>(mIsFirstPartyTrackingResource),
-       static_cast<int>(mIsThirdPartyTrackingResource)));
+  LOG(("HttpBaseChannel::OverrideTrackingFlagsForDocumentCookieAccessor() %p",
+       this));
 
   // The semantics we'd like to achieve here are that document.cookie
   // should follow the same rules that the document is subject to with
   // regards to content blocking. Therefore we need to propagate the
   // same flags from the document channel to the fake channel here.
-  if (aDocumentChannel->GetIsThirdPartyTrackingResource()) {
-    mIsThirdPartyTrackingResource = true;
-  } else {
-    mIsFirstPartyTrackingResource = true;
-  }
-
-  MOZ_ASSERT(!(mIsFirstPartyTrackingResource && mIsThirdPartyTrackingResource));
+
+  mThirdPartyClassificationFlags =
+      aDocumentChannel->GetThirdPartyClassificationFlags();
+  mFirstPartyClassificationFlags =
+      aDocumentChannel->GetFirstPartyClassificationFlags();
+
+  MOZ_ASSERT(
+      !(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetTransferSize(uint64_t* aTransferSize) {
   *aTransferSize = mTransferSize;
   return NS_OK;
 }
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -234,16 +234,21 @@ class HttpBaseChannel : public nsHashPro
   NS_IMETHOD SetChannelId(uint64_t aChannelId) override;
   NS_IMETHOD GetTopLevelContentWindowId(uint64_t *aContentWindowId) override;
   NS_IMETHOD SetTopLevelContentWindowId(uint64_t aContentWindowId) override;
   NS_IMETHOD GetTopLevelOuterContentWindowId(uint64_t *aWindowId) override;
   NS_IMETHOD SetTopLevelOuterContentWindowId(uint64_t aWindowId) override;
   NS_IMETHOD GetIsTrackingResource(bool *aIsTrackingResource) override;
   NS_IMETHOD GetIsThirdPartyTrackingResource(
       bool *aIsTrackingResource) override;
+  NS_IMETHOD GetClassificationFlags(uint32_t *aIsClassificationFlags) override;
+  NS_IMETHOD GetFirstPartyClassificationFlags(
+      uint32_t *aIsClassificationFlags) override;
+  NS_IMETHOD GetThirdPartyClassificationFlags(
+      uint32_t *aIsClassificationFlags) override;
   NS_IMETHOD OverrideTrackingFlagsForDocumentCookieAccessor(
       nsIHttpChannel *aDocumentChannel) override;
   NS_IMETHOD GetFlashPluginState(
       nsIHttpChannel::FlashPluginState *aState) override;
 
   // nsIHttpChannelInternal
   NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
   NS_IMETHOD SetDocumentURI(nsIURI *aDocumentURI) override;
@@ -412,17 +417,17 @@ class HttpBaseChannel : public nsHashPro
   MOZ_MUST_USE nsresult DoApplyContentConversions(
       nsIStreamListener *aNextListener, nsIStreamListener **aNewNextListener);
 
   // Callback on STS thread called by CopyComplete when NS_AsyncCopy()
   // is finished. This function works as a proxy function to dispatch
   // |EnsureUploadStreamIsCloneableComplete| to main thread.
   virtual void OnCopyComplete(nsresult aStatus);
 
-  void SetIsTrackingResource(bool aIsThirdParty);
+  void AddClassificationFlags(uint32_t aFlags, bool aIsThirdParty);
 
   void SetFlashPluginState(nsIHttpChannel::FlashPluginState aState);
 
   const uint64_t &ChannelId() const { return mChannelId; }
 
   void InternalSetUploadStream(nsIInputStream *uploadStream) {
     mUploadStream = uploadStream;
   }
@@ -528,16 +533,19 @@ class HttpBaseChannel : public nsHashPro
   static void CallTypeSniffers(void *aClosure, const uint8_t *aData,
                                uint32_t aCount);
 
   nsresult CheckRedirectLimit(uint32_t aRedirectFlags) const;
 
   bool MaybeWaitForUploadStreamLength(nsIStreamListener *aListener,
                                       nsISupports *aContext);
 
+  bool IsThirdPartyTrackingResource() const;
+  bool IsTrackingResource() const;
+
   friend class PrivateBrowsingChannel<HttpBaseChannel>;
   friend class InterceptFailedOnStop;
 
  protected:
   // this section is for main-thread-only object
   // all the references need to be proxy released on main thread.
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIURI> mOriginalURI;
@@ -657,18 +665,18 @@ class HttpBaseChannel : public nsHashPro
   uint64_t mChannelId;
   uint64_t mReqContentLength;
 
   Atomic<nsresult, ReleaseAcquire> mStatus;
 
   // Use Release-Acquire ordering to ensure the OMT ODA is ignored while channel
   // is canceled on main thread.
   Atomic<bool, ReleaseAcquire> mCanceled;
-  Atomic<bool, ReleaseAcquire> mIsFirstPartyTrackingResource;
-  Atomic<bool, ReleaseAcquire> mIsThirdPartyTrackingResource;
+  Atomic<uint32_t, ReleaseAcquire> mFirstPartyClassificationFlags;
+  Atomic<uint32_t, ReleaseAcquire> mThirdPartyClassificationFlags;
   Atomic<uint32_t, ReleaseAcquire> mFlashPluginState;
 
   uint32_t mLoadFlags;
   uint32_t mCaps;
   uint32_t mClassOfService;
 
   uint32_t mUpgradeToSecure : 1;
   uint32_t mApplyConversion : 1;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1866,24 +1866,25 @@ void HttpChannelChild::ProcessNotifyCook
                                AntiTrackingCommon::NotifyBlockingDecision(
                                    self,
                                    AntiTrackingCommon::BlockingDecision::eBlock,
                                    aRejectedReason);
                              }),
       NS_DISPATCH_NORMAL);
 }
 
-void HttpChannelChild::ProcessNotifyTrackingResource(bool aIsThirdParty) {
+void HttpChannelChild::ProcessNotifyClassificationFlags(
+    uint32_t aClassificationFlags, bool aIsThirdParty) {
   LOG(
-      ("HttpChannelChild::ProcessNotifyTrackingResource thirdparty=%d "
-       "[this=%p]\n",
-       static_cast<int>(aIsThirdParty), this));
+      ("HttpChannelChild::ProcessNotifyClassificationFlags thirdparty=%d "
+       "flags=%" PRIu32 " [this=%p]\n",
+       static_cast<int>(aIsThirdParty), aClassificationFlags, this));
   MOZ_ASSERT(OnSocketThread());
 
-  SetIsTrackingResource(aIsThirdParty);
+  AddClassificationFlags(aClassificationFlags, aIsThirdParty);
 }
 
 void HttpChannelChild::ProcessNotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   LOG(("HttpChannelChild::ProcessNotifyFlashPluginStateChanged [this=%p]\n",
        this));
   MOZ_ASSERT(OnSocketThread());
 
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -261,17 +261,18 @@ class HttpChannelChild final : public PH
   void ProcessOnProgress(const int64_t& aProgress, const int64_t& aProgressMax);
   void ProcessOnStatus(const nsresult& aStatus);
   void ProcessFlushedForDiversion();
   void ProcessDivertMessages();
   void ProcessNotifyChannelClassifierProtectionDisabled(
       uint32_t aAcceptedReason);
   void ProcessNotifyCookieAllowed();
   void ProcessNotifyCookieBlocked(uint32_t aRejectedReason);
-  void ProcessNotifyTrackingResource(bool aIsThirdParty);
+  void ProcessNotifyClassificationFlags(uint32_t aClassificationFlags,
+                                        bool aIsThirdParty);
   void ProcessNotifyFlashPluginStateChanged(
       nsIHttpChannel::FlashPluginState aState);
   void ProcessSetClassifierMatchedInfo(const nsCString& aList,
                                        const nsCString& aProvider,
                                        const nsCString& aFullHash);
 
   // Return true if we need to tell the parent the size of unreported received
   // data
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1843,22 +1843,26 @@ HttpChannelParent::SetClassifierMatchedI
     MOZ_ASSERT(mBgParent);
     Unused << mBgParent->OnSetClassifierMatchedInfo(aList, aProvider,
                                                     aFullHash);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HttpChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
-  LOG(("HttpChannelParent::NotifyTrackingResource thirdparty=%d [this=%p]\n",
-       static_cast<int>(aIsThirdParty), this));
+HttpChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
+                                             bool aIsThirdParty) {
+  LOG(
+      ("HttpChannelParent::NotifyClassificationFlags "
+       "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n",
+       aClassificationFlags, static_cast<int>(aIsThirdParty), this));
   if (!mIPCClosed) {
     MOZ_ASSERT(mBgParent);
-    Unused << mBgParent->OnNotifyTrackingResource(aIsThirdParty);
+    Unused << mBgParent->OnNotifyClassificationFlags(aClassificationFlags,
+                                                     aIsThirdParty);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   LOG(("HttpChannelParent::NotifyFlashPluginStateChanged [this=%p]\n", this));
--- a/netwerk/protocol/http/NullHttpChannel.cpp
+++ b/netwerk/protocol/http/NullHttpChannel.cpp
@@ -84,23 +84,40 @@ NullHttpChannel::SetTopLevelOuterContent
 }
 
 NS_IMETHODIMP
 NullHttpChannel::GetIsTrackingResource(bool *aIsTrackingResource) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
+NullHttpChannel::GetIsThirdPartyTrackingResource(bool *aIsTrackingResource) {
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+NullHttpChannel::GetClassificationFlags(uint32_t *aClassificationFlags) {
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 NullHttpChannel::GetFlashPluginState(
     nsIHttpChannel::FlashPluginState *aResult) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-NullHttpChannel::GetIsThirdPartyTrackingResource(bool *aIsTrackingResource) {
+NullHttpChannel::GetFirstPartyClassificationFlags(
+    uint32_t *aClassificationFlags) {
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+NullHttpChannel::GetThirdPartyClassificationFlags(
+    uint32_t *aClassificationFlags) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullHttpChannel::OverrideTrackingFlagsForDocumentCookieAccessor(
     nsIHttpChannel *aDocumentChannel) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/netwerk/protocol/http/PHttpBackgroundChannel.ipdl
+++ b/netwerk/protocol/http/PHttpBackgroundChannel.ipdl
@@ -59,19 +59,18 @@ child:
   async NotifyChannelClassifierProtectionDisabled(uint32_t aAcceptedReason);
 
   // Tell the child that cookies are allowed for this load.
   async NotifyCookieAllowed();
 
   // Tell the child that tracking cookies are blocked for this load.
   async NotifyCookieBlocked(uint32_t aRejectedReason);
 
-  // Tell the child that the resource being loaded is on the tracking
-  // protection list.
-  async NotifyTrackingResource(bool aIsThirdParty);
+  // Tell the child that the resource being loaded has been classified.
+  async NotifyClassificationFlags(uint32_t aClassificationFlags, bool aIsThirdParty);
 
   // Tell the child that the current channel's document is not allowed to load
   // flash content.
   async NotifyFlashPluginStateChanged(FlashPluginState aState);
 
   // Tell the child information of matched URL againts SafeBrowsing list
   async SetClassifierMatchedInfo(ClassifierInfo info);
 
--- a/netwerk/protocol/http/PTrackingDummyChannel.ipdl
+++ b/netwerk/protocol/http/PTrackingDummyChannel.ipdl
@@ -6,19 +6,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PNecko;
 
 namespace mozilla {
 namespace net {
 
 // This protocol provides a mechanism for the "child intercept" mode of
-// ServiceWorker operation to work correctly with Tracking Protection
-// annotations.  ServiceWorkers should not be allowed for third-party iframes
-// which are annotated as tracking origins.
+// ServiceWorker operation to work correctly with Classified channels.
+// ServiceWorkers should not be allowed for third-party iframes which are
+// annotated as tracking origins.
 //
 // In child intercept mode, the decision to intercept a channel is made in the
 // child process without consulting the parent process.  The decision is based
 // on whether there is a ServiceWorker with a scope covering the URL in question
 // and whether storage is allowed for the origin/URL.  When the
 // "network.cookie.cookieBehavior" preference is set to BEHAVIOR_REJECT_TRACKER,
 // annotated channels are denied storage which means that the ServiceWorker
 // should not intercept the channel.  However, the decision for tracking
@@ -34,14 +34,14 @@ namespace net {
 // to be confident we will never need/want to turn it off.  Then as part of bug
 // 1496997 we can remove this implementation.  Bug 1498259 covers removing this
 // hack in particular.
 protocol PTrackingDummyChannel
 {
   manager PNecko;
 
 child:
-  async __delete__(bool aTrackingResource);
+  async __delete__(uint32_t aClassificationFlags);
 };
 
 } // namespace net
 } // namespace mozilla
 
--- a/netwerk/protocol/http/TrackingDummyChannel.cpp
+++ b/netwerk/protocol/http/TrackingDummyChannel.cpp
@@ -73,38 +73,39 @@ NS_INTERFACE_MAP_BEGIN(TrackingDummyChan
   NS_INTERFACE_MAP_ENTRY_CONCRETE(TrackingDummyChannel)
 NS_INTERFACE_MAP_END
 
 TrackingDummyChannel::TrackingDummyChannel(nsIURI* aURI, nsIURI* aTopWindowURI,
                                            nsresult aTopWindowURIResult,
                                            nsILoadInfo* aLoadInfo)
     : mTopWindowURI(aTopWindowURI),
       mTopWindowURIResult(aTopWindowURIResult),
-      mIsTrackingResource(false) {
+      mClassificationFlags(0) {
   MOZ_ASSERT(XRE_IsParentProcess());
 
   SetOriginalURI(aURI);
   SetLoadInfo(aLoadInfo);
 }
 
 TrackingDummyChannel::~TrackingDummyChannel() {
   NS_ReleaseOnMainThreadSystemGroup("TrackingDummyChannel::mLoadInfo",
                                     mLoadInfo.forget());
   NS_ReleaseOnMainThreadSystemGroup("TrackingDummyChannel::mURI",
                                     mURI.forget());
   NS_ReleaseOnMainThreadSystemGroup("TrackingDummyChannel::mTopWindowURI",
                                     mTopWindowURI.forget());
 }
 
-bool TrackingDummyChannel::IsTrackingResource() const {
-  return mIsTrackingResource;
+uint32_t TrackingDummyChannel::ClassificationFlags() const {
+  return mClassificationFlags;
 }
 
-void TrackingDummyChannel::SetIsTrackingResource() {
-  mIsTrackingResource = true;
+void TrackingDummyChannel::AddClassificationFlags(
+    uint32_t aClassificationFlags) {
+  mClassificationFlags |= aClassificationFlags;
 }
 
 //-----------------------------------------------------------------------------
 // TrackingDummyChannel::nsIChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 TrackingDummyChannel::GetOriginalURI(nsIURI** aOriginalURI) {
--- a/netwerk/protocol/http/TrackingDummyChannel.h
+++ b/netwerk/protocol/http/TrackingDummyChannel.h
@@ -61,29 +61,29 @@ class TrackingDummyChannel final : publi
   };
 
   static StorageAllowedState StorageAllowed(
       nsIChannel* aChannel, const std::function<void(bool)>& aCallback);
 
   TrackingDummyChannel(nsIURI* aURI, nsIURI* aTopWindowURI,
                        nsresult aTopWindowURIResult, nsILoadInfo* aLoadInfo);
 
-  bool IsTrackingResource() const;
+  uint32_t ClassificationFlags() const;
 
-  void SetIsTrackingResource();
+  void AddClassificationFlags(uint32_t);
 
  private:
   ~TrackingDummyChannel();
 
   nsCOMPtr<nsILoadInfo> mLoadInfo;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIURI> mTopWindowURI;
   nsresult mTopWindowURIResult;
 
-  bool mIsTrackingResource;
+  uint32_t mClassificationFlags;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(TrackingDummyChannel, TRACKING_DUMMY_CHANNEL_IID)
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // mozilla_net_TrackingDummyChannel_h
--- a/netwerk/protocol/http/TrackingDummyChannelChild.cpp
+++ b/netwerk/protocol/http/TrackingDummyChannelChild.cpp
@@ -63,29 +63,27 @@ void TrackingDummyChannelChild::Initiali
 
   mChannel = aChannel;
   mURI = aURI;
   mIsThirdParty = aIsThirdParty;
   mCallback = aCallback;
 }
 
 mozilla::ipc::IPCResult TrackingDummyChannelChild::Recv__delete__(
-    const bool& aTrackingResource) {
+    const uint32_t& aClassificationFlags) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!mChannel) {
     return IPC_OK();
   }
 
   nsCOMPtr<nsIHttpChannel> channel = std::move(mChannel);
 
   RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(channel);
-  if (aTrackingResource) {
-    httpChannel->SetIsTrackingResource(mIsThirdParty);
-  }
+  httpChannel->AddClassificationFlags(aClassificationFlags, mIsThirdParty);
 
   bool storageGranted = AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
       httpChannel, mURI, nullptr);
   mCallback(storageGranted);
   return IPC_OK();
 }
 
 }  // namespace net
--- a/netwerk/protocol/http/TrackingDummyChannelChild.h
+++ b/netwerk/protocol/http/TrackingDummyChannelChild.h
@@ -29,17 +29,17 @@ class TrackingDummyChannelChild final : 
   TrackingDummyChannelChild();
   ~TrackingDummyChannelChild();
 
  private:
   void Initialize(nsIHttpChannel* aChannel, nsIURI* aURI, bool aIsThirdParty,
                   const std::function<void(bool)>& aCallback);
 
   mozilla::ipc::IPCResult Recv__delete__(
-      const bool& aTrackingResource) override;
+      const uint32_t& aClassificationFlags) override;
 
   nsCOMPtr<nsIHttpChannel> mChannel;
   nsCOMPtr<nsIURI> mURI;
   std::function<void(bool)> mCallback;
   bool mIsThirdParty;
 };
 
 }  // namespace net
--- a/netwerk/protocol/http/TrackingDummyChannelParent.cpp
+++ b/netwerk/protocol/http/TrackingDummyChannelParent.cpp
@@ -32,17 +32,17 @@ void TrackingDummyChannelParent::Init(ns
   }
 
   RefPtr<TrackingDummyChannel> channel = new TrackingDummyChannel(
       aURI, aTopWindowURI, aTopWindowURIResult, aLoadInfo);
 
   bool willCallback = NS_SUCCEEDED(AsyncUrlChannelClassifier::CheckChannel(
       channel, [self = std::move(self), channel]() {
         if (self->mIPCActive) {
-          Unused << Send__delete__(self, channel->IsTrackingResource());
+          Unused << Send__delete__(self, channel->ClassificationFlags());
         }
       }));
 
   if (willCallback) {
     onExit.release();
   }
 }
 
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -645,17 +645,17 @@ nsresult nsHttpChannel::Connect() {
     LOG(("Resuming from cache is not supported yet"));
     return NS_ERROR_DOCUMENT_NOT_CACHED;
   }
 
   if (ShouldIntercept()) {
     return RedirectToInterceptedChannel();
   }
 
-  bool isTrackingResource = mIsThirdPartyTrackingResource;  // is atomic
+  bool isTrackingResource = IsThirdPartyTrackingResource();
   LOG(("nsHttpChannel %p tracking resource=%d, cos=%u", this,
        isTrackingResource, mClassOfService));
 
   if (isTrackingResource) {
     AddClassFlags(nsIClassOfService::Tail);
   }
 
   if (WaitingForTailUnblock()) {
@@ -2345,17 +2345,17 @@ nsresult nsHttpChannel::ProcessResponse(
   if (!referrer) {
     referrer = mReferrer;
   }
 
   if (referrer) {
     nsCOMPtr<nsILoadContextInfo> lci = GetLoadContextInfo(this);
     mozilla::net::Predictor::UpdateCacheability(
         referrer, mURI, httpStatus, mRequestHead, mResponseHead, lci,
-        mIsThirdPartyTrackingResource);
+        IsThirdPartyTrackingResource());
   }
 
   // Only allow 407 (authentication required) to continue
   if (mTransaction && mTransaction->ProxyConnectFailed() && httpStatus != 407) {
     return ProcessFailedProxyConnect(httpStatus);
   }
 
   MOZ_ASSERT(!mCachedContentIsValid || mRaceCacheWithNetwork,
@@ -3903,17 +3903,17 @@ nsresult nsHttpChannel::OpenCacheEntryIn
 
   if (mPostID) {
     extension.Append(nsPrintfCString("%d", mPostID));
   }
   if (mTRR) {
     extension.Append("TRR");
   }
 
-  if (mIsThirdPartyTrackingResource &&
+  if (IsThirdPartyTrackingResource() &&
       !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(this, mURI,
                                                                nullptr)) {
     nsCOMPtr<nsIURI> topWindowURI;
     rv = GetTopWindowURI(getter_AddRefs(topWindowURI));
     bool isDocument = false;
     if (NS_FAILED(rv) && NS_SUCCEEDED(GetIsMainDocumentChannel(&isDocument)) &&
         isDocument) {
       // For top-level documents, use the document channel's origin to compute
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -490,33 +490,78 @@ interface nsIHttpChannel : nsIChannel
 
     /**
      * ID of the top-level document's inner window.  Identifies the content
      * this channels is being load in.
      */
     [must_use] attribute uint64_t topLevelContentWindowId;
 
     /**
-     * Returns true if the channel has loaded a resource that is on the tracking
-     * protection list.  This is only available if the
-     * privacy.trackingprotection.annotate_channels pref is set and its value
-     * should only be relied on after the channel has established a connection.
+     * Returns the classification flags if the channel has been processed by
+     * URL-Classifier features and is considered first-party.
+     */
+    [infallible] readonly attribute unsigned long firstPartyClassificationFlags;
+
+    /**
+     * Returns the classification flags if the channel has been processed by
+     * URL-Classifier features and is considered third-party with the top
+     * window URI.
+     */
+    [infallible] readonly attribute unsigned long thirdPartyClassificationFlags;
+
+    /*
+     * Returns the classification flags if the channel has been processed by
+     * URL-Classifier features. This value is equal to
+     * "firstPartyClassificationFlags || thirdPartyClassificationFlags".
+     *
+     * Note that top-level channels could be classified as well.
+     * In order to identify third-party resources specifically, use
+     * classificationThirdPartyFlags;
+     */
+    [infallible] readonly attribute unsigned long classificationFlags;
+
+    cenum ClassificationFlags : 32 {
+      /**
+       * The resource is on the fingerprinting list. This is only available if
+       * the privacy.trackingprotection.fingerprinting_annotate_enabled pref.
+       */
+      CLASSIFIED_FINGERPRINTING = 0x01,
+
+      /**
+       * The resource is on the cryptomining list. This is only available if
+       * the privacy.trackingprotection.cryptomining_annotate_enabled pref is set.
+       */
+      CLASSIFIED_CRYPTOMINING = 0x02,
+
+      /**
+       * The resource is on the tracking protection list. This is only available
+       * if the privacy.trackingprotection.annotate_channels pref.
+       */
+      CLASSIFIED_TRACKING = 0x04,
+    };
+
+    /**
+     * Returns true if the channel has loaded a resource that is classified as
+     * tracker.
+     * This is a helper attribute which returns the same value of
+     * (classificationFlags & CLASSIFIED_TRACKING)
      *
      * Note that top-level channels could be marked as tracking
      * resource. In order to identify third-party tracking resources
      * specifically, use isThirdPartyTrackingResource.
      */
     [infallible] readonly attribute boolean isTrackingResource;
 
     /**
-     * Returns true if the channel has loaded a resource that is on the tracking
-     * protection list and is considered third-party with the top window URI.
-     * This is only available if the privacy.trackingprotection.annotate_channels
-     * pref is set and its value should only be relied on after the channel has
-     * established a connection.
+     * Returns the classification flags if the channel has been processed by
+     * URL-Classifier features and is considered third-party with the top
+     * window URI.
+     *
+     * This is a helper attribute which returns the same value of
+     * (thirdPartyClassificationFlags & CLASSIFIED_TRACKING)
      */
     [infallible] readonly attribute boolean isThirdPartyTrackingResource;
 
     /**
      * Returns the allowing status for flash plugin for this channel.
      */
     cenum FlashPluginState : 8 {
       FlashPluginUnknown = 0,
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -706,31 +706,54 @@ nsViewSourceChannel::SetTopLevelOuterCon
 NS_IMETHODIMP
 nsViewSourceChannel::GetIsTrackingResource(bool *aIsTrackingResource) {
   return !mHttpChannel
              ? NS_ERROR_NULL_POINTER
              : mHttpChannel->GetIsTrackingResource(aIsTrackingResource);
 }
 
 NS_IMETHODIMP
-nsViewSourceChannel::GetFlashPluginState(
-    nsIHttpChannel::FlashPluginState *aResult) {
-  return !mHttpChannel ? NS_ERROR_NULL_POINTER
-                       : mHttpChannel->GetFlashPluginState(aResult);
-}
-
-NS_IMETHODIMP
 nsViewSourceChannel::GetIsThirdPartyTrackingResource(
     bool *aIsTrackingResource) {
   return !mHttpChannel ? NS_ERROR_NULL_POINTER
                        : mHttpChannel->GetIsThirdPartyTrackingResource(
                              aIsTrackingResource);
 }
 
 NS_IMETHODIMP
+nsViewSourceChannel::GetClassificationFlags(uint32_t *aClassificationFlags) {
+  return !mHttpChannel
+             ? NS_ERROR_NULL_POINTER
+             : mHttpChannel->GetClassificationFlags(aClassificationFlags);
+}
+
+NS_IMETHODIMP
+nsViewSourceChannel::GetFirstPartyClassificationFlags(
+    uint32_t *aClassificationFlags) {
+  return !mHttpChannel ? NS_ERROR_NULL_POINTER
+                       : mHttpChannel->GetFirstPartyClassificationFlags(
+                             aClassificationFlags);
+}
+
+NS_IMETHODIMP
+nsViewSourceChannel::GetThirdPartyClassificationFlags(
+    uint32_t *aClassificationFlags) {
+  return !mHttpChannel ? NS_ERROR_NULL_POINTER
+                       : mHttpChannel->GetThirdPartyClassificationFlags(
+                             aClassificationFlags);
+}
+
+NS_IMETHODIMP
+nsViewSourceChannel::GetFlashPluginState(
+    nsIHttpChannel::FlashPluginState *aResult) {
+  return !mHttpChannel ? NS_ERROR_NULL_POINTER
+                       : mHttpChannel->GetFlashPluginState(aResult);
+}
+
+NS_IMETHODIMP
 nsViewSourceChannel::OverrideTrackingFlagsForDocumentCookieAccessor(
     nsIHttpChannel *aDocumentChannel) {
   return !mHttpChannel
              ? NS_ERROR_NULL_POINTER
              : mHttpChannel->OverrideTrackingFlagsForDocumentCookieAccessor(
                    aDocumentChannel);
 }
 
--- a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp
+++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp
@@ -33,36 +33,38 @@ namespace {
   "urlclassifier.trackingAnnotationWhitelistTable.testEntries"
 #define URLCLASSIFIER_TRACKING_ANNOTATION_SKIP_URLS \
   "urlclassifier.trackingAnnotationSkipURLs"
 #define TABLE_ANNOTATION_BLACKLIST_PREF "annotation-blacklist-pref"
 #define TABLE_ANNOTATION_WHITELIST_PREF "annotation-whitelist-pref"
 
 StaticRefPtr<UrlClassifierFeatureTrackingAnnotation> gFeatureTrackingAnnotation;
 
-static void SetIsTrackingResourceHelper(nsIChannel* aChannel,
-                                        bool aIsThirdParty) {
+static void SetClassificationFlagsHelper(nsIChannel* aChannel,
+                                         bool aIsThirdParty) {
   MOZ_ASSERT(aChannel);
 
   nsCOMPtr<nsIParentChannel> parentChannel;
   NS_QueryNotificationCallbacks(aChannel, parentChannel);
   if (parentChannel) {
     // This channel is a parent-process proxy for a child process
     // request. We should notify the child process as well.
-    parentChannel->NotifyTrackingResource(aIsThirdParty);
+    parentChannel->NotifyClassificationFlags(
+        nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING, aIsThirdParty);
   }
 
   RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
   if (httpChannel) {
-    httpChannel->SetIsTrackingResource(aIsThirdParty);
+    httpChannel->AddClassificationFlags(nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING,
+                                        aIsThirdParty);
   }
 
   RefPtr<TrackingDummyChannel> dummyChannel = do_QueryObject(aChannel);
   if (dummyChannel) {
-    dummyChannel->SetIsTrackingResource();
+    dummyChannel->AddClassificationFlags(nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING);
   }
 }
 
 static void LowerPriorityHelper(nsIChannel* aChannel) {
   MOZ_ASSERT(aChannel);
 
   bool isBlockingResource = false;
 
@@ -211,17 +213,17 @@ UrlClassifierFeatureTrackingAnnotation::
   bool isAllowListed =
       IsAllowListed(aChannel, AntiTrackingCommon::eTrackingAnnotations);
 
   UC_LOG(
       ("UrlClassifierFeatureTrackingAnnotation::ProcessChannel, annotating "
        "channel[%p]",
        aChannel));
 
-  SetIsTrackingResourceHelper(aChannel, isThirdPartyWithTopLevelWinURI);
+  SetClassificationFlagsHelper(aChannel, isThirdPartyWithTopLevelWinURI);
 
   if (isThirdPartyWithTopLevelWinURI || isAllowListed) {
     // Even with TP disabled, we still want to show the user that there
     // are unblocked trackers on the site, so notify the UI that we loaded
     // tracking content. UI code can treat this notification differently
     // depending on whether TP is enabled or disabled.
     UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
         aChannel, nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT);
--- a/uriloader/exthandler/nsExternalProtocolHandler.cpp
+++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp
@@ -401,17 +401,18 @@ NS_IMETHODIMP nsExtProtocolChannel::Noti
 
 NS_IMETHODIMP nsExtProtocolChannel::SetClassifierMatchedInfo(
     const nsACString &aList, const nsACString &aProvider,
     const nsACString &aFullHash) {
   // nothing to do
   return NS_OK;
 }
 
-NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingResource(bool aIsThirdParty) {
+NS_IMETHODIMP nsExtProtocolChannel::NotifyClassificationFlags(
+    uint32_t aClassificationFlags, bool aIsThirdParty) {
   // nothing to do
   return NS_OK;
 }
 
 NS_IMETHODIMP nsExtProtocolChannel::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   // nothing to do
   return NS_OK;