From c39dc7f1aa2cf41fe907d1c5cfe15bb20f6df4b3 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 14 Mar 2019 17:47:59 +0000 Subject: [PATCH] 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 --HG-- extra : moz-landing-system : lando --- netwerk/base/SimpleChannelParent.cpp | 3 +- netwerk/base/nsIParentChannel.idl | 7 +- netwerk/cookie/CookieServiceParent.h | 2 +- netwerk/protocol/data/DataChannelParent.cpp | 3 +- netwerk/protocol/file/FileChannelParent.cpp | 3 +- netwerk/protocol/ftp/FTPChannelParent.cpp | 3 +- .../http/HttpBackgroundChannelChild.cpp | 15 ++-- .../http/HttpBackgroundChannelChild.h | 3 +- .../http/HttpBackgroundChannelParent.cpp | 19 ++-- .../http/HttpBackgroundChannelParent.h | 5 +- netwerk/protocol/http/HttpBaseChannel.cpp | 90 +++++++++++++------ netwerk/protocol/http/HttpBaseChannel.h | 14 ++- netwerk/protocol/http/HttpChannelChild.cpp | 11 +-- netwerk/protocol/http/HttpChannelChild.h | 3 +- netwerk/protocol/http/HttpChannelParent.cpp | 12 ++- netwerk/protocol/http/NullHttpChannel.cpp | 19 +++- .../protocol/http/PHttpBackgroundChannel.ipdl | 5 +- .../protocol/http/PTrackingDummyChannel.ipdl | 8 +- .../protocol/http/TrackingDummyChannel.cpp | 11 +-- netwerk/protocol/http/TrackingDummyChannel.h | 6 +- .../http/TrackingDummyChannelChild.cpp | 6 +- .../protocol/http/TrackingDummyChannelChild.h | 2 +- .../http/TrackingDummyChannelParent.cpp | 2 +- netwerk/protocol/http/nsHttpChannel.cpp | 6 +- netwerk/protocol/http/nsIHttpChannel.idl | 63 +++++++++++-- .../viewsource/nsViewSourceChannel.cpp | 37 ++++++-- ...UrlClassifierFeatureTrackingAnnotation.cpp | 14 +-- .../exthandler/nsExternalProtocolHandler.cpp | 3 +- 28 files changed, 263 insertions(+), 112 deletions(-) diff --git a/netwerk/base/SimpleChannelParent.cpp b/netwerk/base/SimpleChannelParent.cpp index a56c984c150e..421ab88f98e5 100644 --- a/netwerk/base/SimpleChannelParent.cpp +++ b/netwerk/base/SimpleChannelParent.cpp @@ -48,7 +48,8 @@ SimpleChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) { } NS_IMETHODIMP -SimpleChannelParent::NotifyTrackingResource(bool aIsThirdParty) { +SimpleChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags, + bool aIsThirdParty) { // Nothing to do. return NS_OK; } diff --git a/netwerk/base/nsIParentChannel.idl b/netwerk/base/nsIParentChannel.idl index 16bbd9bfb4b7..84c9e2691308 100644 --- a/netwerk/base/nsIParentChannel.idl +++ b/netwerk/base/nsIParentChannel.idl @@ -67,12 +67,15 @@ interface nsIParentChannel : nsIStreamListener /** * 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. diff --git a/netwerk/cookie/CookieServiceParent.h b/netwerk/cookie/CookieServiceParent.h index 3caf82c681c3..3129bf96c5e6 100644 --- a/netwerk/cookie/CookieServiceParent.h +++ b/netwerk/cookie/CookieServiceParent.h @@ -54,7 +54,7 @@ class CookieServiceParent : public PCookieServiceParent { 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); diff --git a/netwerk/protocol/data/DataChannelParent.cpp b/netwerk/protocol/data/DataChannelParent.cpp index 4868ad63e249..4436c43e0e6c 100644 --- a/netwerk/protocol/data/DataChannelParent.cpp +++ b/netwerk/protocol/data/DataChannelParent.cpp @@ -48,7 +48,8 @@ DataChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) { } NS_IMETHODIMP -DataChannelParent::NotifyTrackingResource(bool aIsThirdParty) { +DataChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags, + bool aIsThirdParty) { // Nothing to do. return NS_OK; } diff --git a/netwerk/protocol/file/FileChannelParent.cpp b/netwerk/protocol/file/FileChannelParent.cpp index 6a9754035a2a..24fb509b6e2e 100644 --- a/netwerk/protocol/file/FileChannelParent.cpp +++ b/netwerk/protocol/file/FileChannelParent.cpp @@ -48,7 +48,8 @@ FileChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) { } NS_IMETHODIMP -FileChannelParent::NotifyTrackingResource(bool aIsThirdParty) { +FileChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags, + bool aIsThirdParty) { // Nothing to do. return NS_OK; } diff --git a/netwerk/protocol/ftp/FTPChannelParent.cpp b/netwerk/protocol/ftp/FTPChannelParent.cpp index 27a7d61516b6..bc91a8ebfecb 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.cpp +++ b/netwerk/protocol/ftp/FTPChannelParent.cpp @@ -515,7 +515,8 @@ FTPChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) { } NS_IMETHODIMP -FTPChannelParent::NotifyTrackingResource(bool aIsThirdParty) { +FTPChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags, + bool aIsThirdParty) { // One day, this should probably be filled in. return NS_OK; } diff --git a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp index 54006a43c0fa..00b9cd499d2c 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp +++ b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp @@ -344,21 +344,22 @@ IPCResult HttpBackgroundChannelChild::RecvNotifyCookieBlocked( 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(aIsThirdParty), this)); + ("HttpBackgroundChannelChild::RecvNotifyClassificationFlags " + "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n", + aClassificationFlags, static_cast(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(); } diff --git a/netwerk/protocol/http/HttpBackgroundChannelChild.h b/netwerk/protocol/http/HttpBackgroundChannelChild.h index f103a2945791..c4829b7465eb 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelChild.h +++ b/netwerk/protocol/http/HttpBackgroundChannelChild.h @@ -71,7 +71,8 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild { 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); diff --git a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp index 77857bf27cb0..03451d6a9fd1 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp +++ b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp @@ -405,11 +405,12 @@ bool HttpBackgroundChannelParent::OnNotifyCookieBlocked( 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(aIsThirdParty), this)); + ("HttpBackgroundChannelParent::OnNotifyClassificationFlags " + "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n", + aClassificationFlags, static_cast(aIsThirdParty), this)); AssertIsInMainProcess(); if (NS_WARN_IF(!mIPCOpened)) { @@ -419,10 +420,10 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingResource(bool aIsThirdParty) { if (!IsOnBackgroundThread()) { MutexAutoLock lock(mBgThreadMutex); nsresult rv = mBackgroundThread->Dispatch( - NewRunnableMethod( - "net::HttpBackgroundChannelParent::OnNotifyTrackingResource", this, - &HttpBackgroundChannelParent::OnNotifyTrackingResource, - aIsThirdParty), + NewRunnableMethod( + "net::HttpBackgroundChannelParent::OnNotifyClassificationFlags", + this, &HttpBackgroundChannelParent::OnNotifyClassificationFlags, + aClassificationFlags, aIsThirdParty), NS_DISPATCH_NORMAL); MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); @@ -430,7 +431,7 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingResource(bool aIsThirdParty) { return NS_SUCCEEDED(rv); } - return SendNotifyTrackingResource(aIsThirdParty); + return SendNotifyClassificationFlags(aClassificationFlags, aIsThirdParty); } bool HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged( diff --git a/netwerk/protocol/http/HttpBackgroundChannelParent.h b/netwerk/protocol/http/HttpBackgroundChannelParent.h index e61d4a20f88c..d83d7f60c32e 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelParent.h +++ b/netwerk/protocol/http/HttpBackgroundChannelParent.h @@ -73,8 +73,9 @@ class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent { // 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); diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index e0dc72f9856d..67ae3b0f4bec 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -168,8 +168,8 @@ HttpBaseChannel::HttpBaseChannel() mReqContentLength(0U), mStatus(NS_OK), mCanceled(false), - mIsFirstPartyTrackingResource(false), - mIsThirdPartyTrackingResource(false), + mFirstPartyClassificationFlags(0), + mThirdPartyClassificationFlags(0), mFlashPluginState(nsIHttpChannel::FlashPluginUnknown), mLoadFlags(LOAD_NORMAL), mCaps(0), @@ -308,16 +308,17 @@ void HttpBaseChannel::ReleaseMainThreadOnlyReferences() { NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease))); } -void HttpBaseChannel::SetIsTrackingResource(bool aIsThirdParty) { - LOG(("HttpBaseChannel::SetIsTrackingResource thirdparty=%d %p", - static_cast(aIsThirdParty), this)); +void HttpBaseChannel::AddClassificationFlags(uint32_t aClassificationFlags, + bool aIsThirdParty) { + LOG( + ("HttpBaseChannel::AddClassificationFlags classificationFlags=%d " + "thirdparty=%d %p", + aClassificationFlags, static_cast(aIsThirdParty), this)); if (aIsThirdParty) { - MOZ_ASSERT(!mIsFirstPartyTrackingResource); - mIsThirdPartyTrackingResource = true; + mThirdPartyClassificationFlags |= aClassificationFlags; } else { - MOZ_ASSERT(!mIsThirdPartyTrackingResource); - mIsFirstPartyTrackingResource = true; + mFirstPartyClassificationFlags |= aClassificationFlags; } } @@ -1469,18 +1470,59 @@ NS_IMETHODIMP HttpBaseChannel::SetTopLevelContentWindowId(uint64_t 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) { - MOZ_ASSERT(!(mIsFirstPartyTrackingResource && mIsThirdPartyTrackingResource)); - *aIsTrackingResource = mIsThirdPartyTrackingResource; + *aIsTrackingResource = IsThirdPartyTrackingResource(); + return NS_OK; +} + +NS_IMETHODIMP +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; } @@ -1494,23 +1536,21 @@ HttpBaseChannel::GetFlashPluginState(nsIHttpChannel::FlashPluginState* aState) { NS_IMETHODIMP HttpBaseChannel::OverrideTrackingFlagsForDocumentCookieAccessor( nsIHttpChannel* aDocumentChannel) { - LOG( - ("HttpBaseChannel::OverrideTrackingFlagsForDocumentCookieAccessor() %p " - "mIsFirstPartyTrackingResource=%d mIsThirdPartyTrackingResource=%d", - this, static_cast(mIsFirstPartyTrackingResource), - static_cast(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; } diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 86ac230cb99c..b2736fa22868 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -239,6 +239,11 @@ class HttpBaseChannel : public nsHashPropertyBag, 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( @@ -417,7 +422,7 @@ class HttpBaseChannel : public nsHashPropertyBag, // |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); @@ -533,6 +538,9 @@ class HttpBaseChannel : public nsHashPropertyBag, bool MaybeWaitForUploadStreamLength(nsIStreamListener *aListener, nsISupports *aContext); + bool IsThirdPartyTrackingResource() const; + bool IsTrackingResource() const; + friend class PrivateBrowsingChannel; friend class InterceptFailedOnStop; @@ -662,8 +670,8 @@ class HttpBaseChannel : public nsHashPropertyBag, // Use Release-Acquire ordering to ensure the OMT ODA is ignored while channel // is canceled on main thread. Atomic mCanceled; - Atomic mIsFirstPartyTrackingResource; - Atomic mIsThirdPartyTrackingResource; + Atomic mFirstPartyClassificationFlags; + Atomic mThirdPartyClassificationFlags; Atomic mFlashPluginState; uint32_t mLoadFlags; diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index f41679a1f8e3..c828ad6896d2 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1871,14 +1871,15 @@ void HttpChannelChild::ProcessNotifyCookieBlocked(uint32_t 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(aIsThirdParty), this)); + ("HttpChannelChild::ProcessNotifyClassificationFlags thirdparty=%d " + "flags=%" PRIu32 " [this=%p]\n", + static_cast(aIsThirdParty), aClassificationFlags, this)); MOZ_ASSERT(OnSocketThread()); - SetIsTrackingResource(aIsThirdParty); + AddClassificationFlags(aClassificationFlags, aIsThirdParty); } void HttpChannelChild::ProcessNotifyFlashPluginStateChanged( diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h index 3a4ae60f068c..31bdccecfad7 100644 --- a/netwerk/protocol/http/HttpChannelChild.h +++ b/netwerk/protocol/http/HttpChannelChild.h @@ -266,7 +266,8 @@ class HttpChannelChild final : public PHttpChannelChild, 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, diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 6490f95faed9..1c9628ad1a18 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -1848,12 +1848,16 @@ HttpChannelParent::SetClassifierMatchedInfo(const nsACString& aList, } NS_IMETHODIMP -HttpChannelParent::NotifyTrackingResource(bool aIsThirdParty) { - LOG(("HttpChannelParent::NotifyTrackingResource thirdparty=%d [this=%p]\n", - static_cast(aIsThirdParty), this)); +HttpChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags, + bool aIsThirdParty) { + LOG( + ("HttpChannelParent::NotifyClassificationFlags " + "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n", + aClassificationFlags, static_cast(aIsThirdParty), this)); if (!mIPCClosed) { MOZ_ASSERT(mBgParent); - Unused << mBgParent->OnNotifyTrackingResource(aIsThirdParty); + Unused << mBgParent->OnNotifyClassificationFlags(aClassificationFlags, + aIsThirdParty); } return NS_OK; } diff --git a/netwerk/protocol/http/NullHttpChannel.cpp b/netwerk/protocol/http/NullHttpChannel.cpp index 34fd8581bad9..5d5d36c596f7 100644 --- a/netwerk/protocol/http/NullHttpChannel.cpp +++ b/netwerk/protocol/http/NullHttpChannel.cpp @@ -88,6 +88,16 @@ 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) { @@ -95,7 +105,14 @@ NullHttpChannel::GetFlashPluginState( } 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; } diff --git a/netwerk/protocol/http/PHttpBackgroundChannel.ipdl b/netwerk/protocol/http/PHttpBackgroundChannel.ipdl index 30e075e09482..67e064b0ec00 100644 --- a/netwerk/protocol/http/PHttpBackgroundChannel.ipdl +++ b/netwerk/protocol/http/PHttpBackgroundChannel.ipdl @@ -64,9 +64,8 @@ child: // 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. diff --git a/netwerk/protocol/http/PTrackingDummyChannel.ipdl b/netwerk/protocol/http/PTrackingDummyChannel.ipdl index 3703f5093d99..db37c07dcdd9 100644 --- a/netwerk/protocol/http/PTrackingDummyChannel.ipdl +++ b/netwerk/protocol/http/PTrackingDummyChannel.ipdl @@ -11,9 +11,9 @@ 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 @@ -39,7 +39,7 @@ protocol PTrackingDummyChannel manager PNecko; child: - async __delete__(bool aTrackingResource); + async __delete__(uint32_t aClassificationFlags); }; } // namespace net diff --git a/netwerk/protocol/http/TrackingDummyChannel.cpp b/netwerk/protocol/http/TrackingDummyChannel.cpp index 8cc864bdc686..1fdb0047f9fd 100644 --- a/netwerk/protocol/http/TrackingDummyChannel.cpp +++ b/netwerk/protocol/http/TrackingDummyChannel.cpp @@ -78,7 +78,7 @@ TrackingDummyChannel::TrackingDummyChannel(nsIURI* aURI, nsIURI* aTopWindowURI, nsILoadInfo* aLoadInfo) : mTopWindowURI(aTopWindowURI), mTopWindowURIResult(aTopWindowURIResult), - mIsTrackingResource(false) { + mClassificationFlags(0) { MOZ_ASSERT(XRE_IsParentProcess()); SetOriginalURI(aURI); @@ -94,12 +94,13 @@ TrackingDummyChannel::~TrackingDummyChannel() { 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; } //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/TrackingDummyChannel.h b/netwerk/protocol/http/TrackingDummyChannel.h index 7c9b6e99c852..e677a5b94073 100644 --- a/netwerk/protocol/http/TrackingDummyChannel.h +++ b/netwerk/protocol/http/TrackingDummyChannel.h @@ -66,9 +66,9 @@ class TrackingDummyChannel final : public nsIChannel, TrackingDummyChannel(nsIURI* aURI, nsIURI* aTopWindowURI, nsresult aTopWindowURIResult, nsILoadInfo* aLoadInfo); - bool IsTrackingResource() const; + uint32_t ClassificationFlags() const; - void SetIsTrackingResource(); + void AddClassificationFlags(uint32_t); private: ~TrackingDummyChannel(); @@ -78,7 +78,7 @@ class TrackingDummyChannel final : public nsIChannel, nsCOMPtr mTopWindowURI; nsresult mTopWindowURIResult; - bool mIsTrackingResource; + uint32_t mClassificationFlags; }; NS_DEFINE_STATIC_IID_ACCESSOR(TrackingDummyChannel, TRACKING_DUMMY_CHANNEL_IID) diff --git a/netwerk/protocol/http/TrackingDummyChannelChild.cpp b/netwerk/protocol/http/TrackingDummyChannelChild.cpp index 0511e6e128de..91fc6dda91fb 100644 --- a/netwerk/protocol/http/TrackingDummyChannelChild.cpp +++ b/netwerk/protocol/http/TrackingDummyChannelChild.cpp @@ -68,7 +68,7 @@ void TrackingDummyChannelChild::Initialize( } mozilla::ipc::IPCResult TrackingDummyChannelChild::Recv__delete__( - const bool& aTrackingResource) { + const uint32_t& aClassificationFlags) { MOZ_ASSERT(NS_IsMainThread()); if (!mChannel) { @@ -78,9 +78,7 @@ mozilla::ipc::IPCResult TrackingDummyChannelChild::Recv__delete__( nsCOMPtr channel = std::move(mChannel); RefPtr httpChannel = do_QueryObject(channel); - if (aTrackingResource) { - httpChannel->SetIsTrackingResource(mIsThirdParty); - } + httpChannel->AddClassificationFlags(aClassificationFlags, mIsThirdParty); bool storageGranted = AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( httpChannel, mURI, nullptr); diff --git a/netwerk/protocol/http/TrackingDummyChannelChild.h b/netwerk/protocol/http/TrackingDummyChannelChild.h index 20f5cd6671ba..49b1a656cdbd 100644 --- a/netwerk/protocol/http/TrackingDummyChannelChild.h +++ b/netwerk/protocol/http/TrackingDummyChannelChild.h @@ -34,7 +34,7 @@ class TrackingDummyChannelChild final : public PTrackingDummyChannelChild { const std::function& aCallback); mozilla::ipc::IPCResult Recv__delete__( - const bool& aTrackingResource) override; + const uint32_t& aClassificationFlags) override; nsCOMPtr mChannel; nsCOMPtr mURI; diff --git a/netwerk/protocol/http/TrackingDummyChannelParent.cpp b/netwerk/protocol/http/TrackingDummyChannelParent.cpp index 82ecc3ac6ce9..d4d8dedb1feb 100644 --- a/netwerk/protocol/http/TrackingDummyChannelParent.cpp +++ b/netwerk/protocol/http/TrackingDummyChannelParent.cpp @@ -37,7 +37,7 @@ void TrackingDummyChannelParent::Init(nsIURI* aURI, nsIURI* aTopWindowURI, 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()); } })); diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index c46459dc1318..7ee81dc85baf 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -650,7 +650,7 @@ nsresult nsHttpChannel::Connect() { return RedirectToInterceptedChannel(); } - bool isTrackingResource = mIsThirdPartyTrackingResource; // is atomic + bool isTrackingResource = IsThirdPartyTrackingResource(); LOG(("nsHttpChannel %p tracking resource=%d, cos=%u", this, isTrackingResource, mClassOfService)); @@ -2350,7 +2350,7 @@ nsresult nsHttpChannel::ProcessResponse() { nsCOMPtr lci = GetLoadContextInfo(this); mozilla::net::Predictor::UpdateCacheability( referrer, mURI, httpStatus, mRequestHead, mResponseHead, lci, - mIsThirdPartyTrackingResource); + IsThirdPartyTrackingResource()); } // Only allow 407 (authentication required) to continue @@ -3908,7 +3908,7 @@ nsresult nsHttpChannel::OpenCacheEntryInternal( extension.Append("TRR"); } - if (mIsThirdPartyTrackingResource && + if (IsThirdPartyTrackingResource() && !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(this, mURI, nullptr)) { nsCOMPtr topWindowURI; diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl index 6aadf4458483..4d7b3956ace7 100644 --- a/netwerk/protocol/http/nsIHttpChannel.idl +++ b/netwerk/protocol/http/nsIHttpChannel.idl @@ -495,10 +495,54 @@ interface nsIHttpChannel : nsIChannel [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 @@ -507,11 +551,12 @@ interface nsIHttpChannel : nsIChannel [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; diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp index 7ec3e1a1e01e..ef019c3c683f 100644 --- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp @@ -710,13 +710,6 @@ nsViewSourceChannel::GetIsTrackingResource(bool *aIsTrackingResource) { : 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) { @@ -725,6 +718,36 @@ nsViewSourceChannel::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) { diff --git a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp index 6bb1d49cfeee..d258c971c7f3 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp @@ -38,8 +38,8 @@ namespace { StaticRefPtr gFeatureTrackingAnnotation; -static void SetIsTrackingResourceHelper(nsIChannel* aChannel, - bool aIsThirdParty) { +static void SetClassificationFlagsHelper(nsIChannel* aChannel, + bool aIsThirdParty) { MOZ_ASSERT(aChannel); nsCOMPtr parentChannel; @@ -47,17 +47,19 @@ static void SetIsTrackingResourceHelper(nsIChannel* aChannel, 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 httpChannel = do_QueryObject(aChannel); if (httpChannel) { - httpChannel->SetIsTrackingResource(aIsThirdParty); + httpChannel->AddClassificationFlags(nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING, + aIsThirdParty); } RefPtr dummyChannel = do_QueryObject(aChannel); if (dummyChannel) { - dummyChannel->SetIsTrackingResource(); + dummyChannel->AddClassificationFlags(nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING); } } @@ -216,7 +218,7 @@ UrlClassifierFeatureTrackingAnnotation::ProcessChannel(nsIChannel* aChannel, "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 diff --git a/uriloader/exthandler/nsExternalProtocolHandler.cpp b/uriloader/exthandler/nsExternalProtocolHandler.cpp index 67e420b4bf95..022b8d1ed865 100644 --- a/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -406,7 +406,8 @@ NS_IMETHODIMP nsExtProtocolChannel::SetClassifierMatchedInfo( return NS_OK; } -NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingResource(bool aIsThirdParty) { +NS_IMETHODIMP nsExtProtocolChannel::NotifyClassificationFlags( + uint32_t aClassificationFlags, bool aIsThirdParty) { // nothing to do return NS_OK; }