diff --git a/netwerk/url-classifier/UrlClassifierCommon.cpp b/netwerk/url-classifier/UrlClassifierCommon.cpp index 3a67e5380dd6..dae8e92c4716 100644 --- a/netwerk/url-classifier/UrlClassifierCommon.cpp +++ b/netwerk/url-classifier/UrlClassifierCommon.cpp @@ -88,19 +88,8 @@ UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled( } /* static */ bool UrlClassifierCommon::ShouldEnableClassifier( - nsIChannel* aChannel, - AntiTrackingCommon::ContentBlockingAllowListPurpose aBlockingPurpose) { + nsIChannel* aChannel) { MOZ_ASSERT(aChannel); - MOZ_ASSERT(aBlockingPurpose == AntiTrackingCommon::eTrackingProtection || - aBlockingPurpose == AntiTrackingCommon::eTrackingAnnotations || - aBlockingPurpose == AntiTrackingCommon::eFingerprinting || - aBlockingPurpose == AntiTrackingCommon::eCryptomining); - - nsCOMPtr channel = do_QueryInterface(aChannel); - if (!channel) { - UC_LOG(("nsChannelClassifier: Not an HTTP channel")); - return false; - } nsCOMPtr chanURI; nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI)); @@ -112,86 +101,31 @@ UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled( return false; } - nsCOMPtr ios = services::GetIOService(); - if (NS_WARN_IF(!ios)) { - return false; - } - - nsCOMPtr topWinURI; - rv = channel->GetTopWindowURI(getter_AddRefs(topWinURI)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - if (!topWinURI && StaticPrefs::channelclassifier_allowlist_example()) { - UC_LOG(("nsChannelClassifier: Allowlisting test domain")); - rv = ios->NewURI(NS_LITERAL_CSTRING("http://allowlisted.example.com"), - nullptr, nullptr, getter_AddRefs(topWinURI)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - } - - bool isAllowListed; - rv = AntiTrackingCommon::IsOnContentBlockingAllowList( - topWinURI, NS_UsePrivateBrowsing(aChannel), aBlockingPurpose, - isAllowListed); - if (NS_FAILED(rv)) { // normal for some loads, no need to print a warning - return false; - } - - if (isAllowListed) { - if (UC_LOG_ENABLED()) { - nsCString chanSpec = chanURI->GetSpecOrDefault(); - chanSpec.Truncate( - std::min(chanSpec.Length(), UrlClassifierCommon::sMaxSpecLength)); - UC_LOG(("nsChannelClassifier: User override on channel[%p] (%s)", - aChannel, chanSpec.get())); - } - - // Channel classifier protection will be disabled so update the security - // state of the document and fire a secure change event. If we can't get the - // window for the channel, then the shield won't show up so we can't send an - // event to the securityUI anyway. - - uint32_t event = 0; - switch (aBlockingPurpose) { - case AntiTrackingCommon::eTrackingProtection: - MOZ_FALLTHROUGH; - case AntiTrackingCommon::eTrackingAnnotations: - event = nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT; - break; - - case AntiTrackingCommon::eFingerprinting: - event = nsIWebProgressListener::STATE_LOADED_FINGERPRINTING_CONTENT; - break; - - case AntiTrackingCommon::eCryptomining: - event = nsIWebProgressListener::STATE_LOADED_CRYPTOMINING_CONTENT; - break; - - default: - MOZ_CRASH("Invalidate blocking purpose."); - } - - UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(aChannel, - event); - - return false; - } - // Tracking protection will be enabled so return without updating // the security state. If any channels are subsequently cancelled // (page elements blocked) the state will be then updated. if (UC_LOG_ENABLED()) { + nsCOMPtr topWinURI; + nsCOMPtr channel = do_QueryInterface(aChannel); + if (!channel) { + UC_LOG(("nsChannelClassifier: Not an HTTP channel")); + return false; + } + + nsresult rv = channel->GetTopWindowURI(getter_AddRefs(topWinURI)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + nsCString chanSpec = chanURI->GetSpecOrDefault(); chanSpec.Truncate( std::min(chanSpec.Length(), UrlClassifierCommon::sMaxSpecLength)); - nsCString topWinSpec = topWinURI->GetSpecOrDefault(); + nsCString topWinSpec = topWinURI ? topWinURI->GetSpecOrDefault() + : NS_LITERAL_CSTRING("(null)"); topWinSpec.Truncate( std::min(topWinSpec.Length(), UrlClassifierCommon::sMaxSpecLength)); UC_LOG( - ("nsChannelClassifier: Enabling tracking protection checks on " + ("nsChannelClassifier: Enabling url classifier checks on " "channel[%p] with uri %s for toplevel window uri %s", aChannel, chanSpec.get(), topWinSpec.get())); } diff --git a/netwerk/url-classifier/UrlClassifierCommon.h b/netwerk/url-classifier/UrlClassifierCommon.h index 74188156043f..bcd4b3b74883 100644 --- a/netwerk/url-classifier/UrlClassifierCommon.h +++ b/netwerk/url-classifier/UrlClassifierCommon.h @@ -30,9 +30,7 @@ class UrlClassifierCommon final { static void NotifyChannelClassifierProtectionDisabled( nsIChannel* aChannel, uint32_t aAcceptedReason); - static bool ShouldEnableClassifier( - nsIChannel* aChannel, - AntiTrackingCommon::ContentBlockingAllowListPurpose aBlockingPurpose); + static bool ShouldEnableClassifier(nsIChannel* aChannel); static nsresult SetBlockedContent(nsIChannel* channel, nsresult aErrorCode, const nsACString& aList, diff --git a/netwerk/url-classifier/UrlClassifierFeatureBase.cpp b/netwerk/url-classifier/UrlClassifierFeatureBase.cpp index 914f3753fcaf..ec83f437caee 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureBase.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureBase.cpp @@ -159,5 +159,65 @@ UrlClassifierFeatureBase::GetSkipHostList(nsACString& aList) { return NS_OK; } +bool UrlClassifierFeatureBase::IsAllowListed( + nsIChannel* aChannel, + AntiTrackingCommon::ContentBlockingAllowListPurpose aPurpose) { + MOZ_ASSERT(aPurpose == AntiTrackingCommon::eTrackingProtection || + aPurpose == AntiTrackingCommon::eTrackingAnnotations || + aPurpose == AntiTrackingCommon::eFingerprinting || + aPurpose == AntiTrackingCommon::eCryptomining); + + nsCOMPtr channel = do_QueryInterface(aChannel); + if (!channel) { + UC_LOG(("nsChannelClassifier: Not an HTTP channel")); + return false; + } + + nsCOMPtr topWinURI; + nsresult rv = channel->GetTopWindowURI(getter_AddRefs(topWinURI)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + + if (!topWinURI && StaticPrefs::channelclassifier_allowlist_example()) { + UC_LOG(("nsChannelClassifier: Allowlisting test domain")); + nsCOMPtr ios = services::GetIOService(); + if (NS_WARN_IF(!ios)) { + return false; + } + + rv = ios->NewURI(NS_LITERAL_CSTRING("http://allowlisted.example.com"), + nullptr, nullptr, getter_AddRefs(topWinURI)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + } + + bool isAllowListed = false; + rv = AntiTrackingCommon::IsOnContentBlockingAllowList( + topWinURI, NS_UsePrivateBrowsing(aChannel), aPurpose, isAllowListed); + if (NS_FAILED(rv)) { // normal for some loads, no need to print a warning + return false; + } + + if (isAllowListed) { + if (UC_LOG_ENABLED()) { + nsCOMPtr chanURI; + nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return isAllowListed; + } + + nsCString chanSpec = chanURI->GetSpecOrDefault(); + chanSpec.Truncate( + std::min(chanSpec.Length(), UrlClassifierCommon::sMaxSpecLength)); + UC_LOG(("nsChannelClassifier: User override on channel[%p] (%s)", + aChannel, chanSpec.get())); + } + } + + return isAllowListed; +} + } // namespace net } // namespace mozilla diff --git a/netwerk/url-classifier/UrlClassifierFeatureBase.h b/netwerk/url-classifier/UrlClassifierFeatureBase.h index 79b35bf6daf0..176c6ca9d285 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureBase.h +++ b/netwerk/url-classifier/UrlClassifierFeatureBase.h @@ -10,6 +10,7 @@ #include "nsIUrlClassifierFeature.h" #include "nsTArray.h" #include "nsString.h" +#include "mozilla/AntiTrackingCommon.h" namespace mozilla { namespace net { @@ -52,6 +53,10 @@ class UrlClassifierFeatureBase : public nsIUrlClassifierFeature { void InitializePreferences(); void ShutdownPreferences(); + bool IsAllowListed( + nsIChannel* aChannel, + AntiTrackingCommon::ContentBlockingAllowListPurpose aPurpose); + private: nsCString mName; diff --git a/netwerk/url-classifier/UrlClassifierFeatureCryptomining.cpp b/netwerk/url-classifier/UrlClassifierFeatureCryptomining.cpp index dbe4d5d73939..b4fbbe881986 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureCryptomining.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureCryptomining.cpp @@ -101,8 +101,7 @@ UrlClassifierFeatureCryptomining::MaybeCreate(nsIChannel* aChannel) { return nullptr; } - if (!UrlClassifierCommon::ShouldEnableClassifier( - aChannel, AntiTrackingCommon::eCryptomining)) { + if (!UrlClassifierCommon::ShouldEnableClassifier(aChannel)) { return nullptr; } @@ -133,22 +132,37 @@ UrlClassifierFeatureCryptomining::ProcessChannel(nsIChannel* aChannel, NS_ENSURE_ARG_POINTER(aChannel); NS_ENSURE_ARG_POINTER(aShouldContinue); + bool isAllowListed = + IsAllowListed(aChannel, AntiTrackingCommon::eCryptomining); + // This is a blocking feature. - *aShouldContinue = false; + *aShouldContinue = isAllowListed; - UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_CRYPTOMINING_URI, - aList, EmptyCString(), EmptyCString()); - - UC_LOG( - ("UrlClassifierFeatureCryptomining::ProcessChannel, cancelling " - "channel[%p]", - aChannel)); - nsCOMPtr httpChannel = do_QueryInterface(aChannel); - - if (httpChannel) { - Unused << httpChannel->CancelByChannelClassifier(NS_ERROR_CRYPTOMINING_URI); + if (isAllowListed) { + // Even with cryptomining blocking disabled, we still want to show the user + // that there are unblocked cryptominers on the site, so notify the UI that + // we loaded cryptomining content. UI code can treat this notification + // differently depending on whether cryptomining blocking is enabled or + // disabled. + UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled( + aChannel, nsIWebProgressListener::STATE_LOADED_CRYPTOMINING_CONTENT); } else { - Unused << aChannel->Cancel(NS_ERROR_CRYPTOMINING_URI); + UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_CRYPTOMINING_URI, + aList, EmptyCString(), + EmptyCString()); + + UC_LOG( + ("UrlClassifierFeatureCryptomining::ProcessChannel, cancelling " + "channel[%p]", + aChannel)); + nsCOMPtr httpChannel = do_QueryInterface(aChannel); + + if (httpChannel) { + Unused << httpChannel->CancelByChannelClassifier( + NS_ERROR_CRYPTOMINING_URI); + } else { + Unused << aChannel->Cancel(NS_ERROR_CRYPTOMINING_URI); + } } return NS_OK; diff --git a/netwerk/url-classifier/UrlClassifierFeatureFingerprinting.cpp b/netwerk/url-classifier/UrlClassifierFeatureFingerprinting.cpp index 490d71df0347..e90ff036db3e 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureFingerprinting.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureFingerprinting.cpp @@ -103,8 +103,7 @@ UrlClassifierFeatureFingerprinting::MaybeCreate(nsIChannel* aChannel) { return nullptr; } - if (!UrlClassifierCommon::ShouldEnableClassifier( - aChannel, AntiTrackingCommon::eFingerprinting)) { + if (!UrlClassifierCommon::ShouldEnableClassifier(aChannel)) { return nullptr; } @@ -135,23 +134,37 @@ UrlClassifierFeatureFingerprinting::ProcessChannel(nsIChannel* aChannel, NS_ENSURE_ARG_POINTER(aChannel); NS_ENSURE_ARG_POINTER(aShouldContinue); + bool isAllowListed = + IsAllowListed(aChannel, AntiTrackingCommon::eFingerprinting); + // This is a blocking feature. - *aShouldContinue = false; + *aShouldContinue = isAllowListed; - UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_FINGERPRINTING_URI, - aList, EmptyCString(), EmptyCString()); - - UC_LOG( - ("UrlClassifierFeatureFingerprinting::ProcessChannel, cancelling " - "channel[%p]", - aChannel)); - nsCOMPtr httpChannel = do_QueryInterface(aChannel); - - if (httpChannel) { - Unused << httpChannel->CancelByChannelClassifier( - NS_ERROR_FINGERPRINTING_URI); + if (isAllowListed) { + // Even with fingerprinting blocking 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 fingerprinting blocking is enabled or + // not. + UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled( + aChannel, nsIWebProgressListener::STATE_LOADED_FINGERPRINTING_CONTENT); } else { - Unused << aChannel->Cancel(NS_ERROR_FINGERPRINTING_URI); + UrlClassifierCommon::SetBlockedContent(aChannel, + NS_ERROR_FINGERPRINTING_URI, aList, + EmptyCString(), EmptyCString()); + + UC_LOG( + ("UrlClassifierFeatureFingerprinting::ProcessChannel, cancelling " + "channel[%p]", + aChannel)); + nsCOMPtr httpChannel = do_QueryInterface(aChannel); + + if (httpChannel) { + Unused << httpChannel->CancelByChannelClassifier( + NS_ERROR_FINGERPRINTING_URI); + } else { + Unused << aChannel->Cancel(NS_ERROR_FINGERPRINTING_URI); + } } return NS_OK; diff --git a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp index 8d84f6ea8f3d..5a981da81954 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp @@ -154,8 +154,7 @@ UrlClassifierFeatureTrackingAnnotation::MaybeCreate(nsIChannel* aChannel) { return nullptr; } - if (!UrlClassifierCommon::ShouldEnableClassifier( - aChannel, AntiTrackingCommon::eTrackingAnnotations)) { + if (!UrlClassifierCommon::ShouldEnableClassifier(aChannel)) { return nullptr; } @@ -205,6 +204,9 @@ UrlClassifierFeatureTrackingAnnotation::ProcessChannel(nsIChannel* aChannel, bool isThirdPartyWithTopLevelWinURI = nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel, chanURI); + bool isAllowListed = + IsAllowListed(aChannel, AntiTrackingCommon::eTrackingAnnotations); + UC_LOG( ("UrlClassifierFeatureTrackingAnnotation::ProcessChannel, annotating " "channel[%p]", @@ -212,17 +214,18 @@ UrlClassifierFeatureTrackingAnnotation::ProcessChannel(nsIChannel* aChannel, SetIsTrackingResourceHelper(aChannel, isThirdPartyWithTopLevelWinURI); - if (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); + } - if (StaticPrefs::privacy_trackingprotection_lower_network_priority()) { - LowerPriorityHelper(aChannel); - } + if (isThirdPartyWithTopLevelWinURI && + StaticPrefs::privacy_trackingprotection_lower_network_priority()) { + LowerPriorityHelper(aChannel); } return NS_OK; diff --git a/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp b/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp index 4bf9b6f06d16..3e4a172c8ba5 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp @@ -101,8 +101,7 @@ UrlClassifierFeatureTrackingProtection::MaybeCreate(nsIChannel* aChannel) { return nullptr; } - if (!UrlClassifierCommon::ShouldEnableClassifier( - aChannel, AntiTrackingCommon::eTrackingProtection)) { + if (!UrlClassifierCommon::ShouldEnableClassifier(aChannel)) { return nullptr; } @@ -136,21 +135,26 @@ UrlClassifierFeatureTrackingProtection::ProcessChannel(nsIChannel* aChannel, NS_ENSURE_ARG_POINTER(aChannel); NS_ENSURE_ARG_POINTER(aShouldContinue); + bool isAllowListed = + IsAllowListed(aChannel, AntiTrackingCommon::eTrackingProtection); + // This is a blocking feature. - *aShouldContinue = false; + *aShouldContinue = isAllowListed; - UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_TRACKING_URI, aList, - EmptyCString(), EmptyCString()); + if (isAllowListed) { + UrlClassifierCommon::SetBlockedContent( + aChannel, NS_ERROR_TRACKING_URI, aList, EmptyCString(), EmptyCString()); - UC_LOG( - ("UrlClassifierFeatureTrackingProtection::ProcessChannel, cancelling " - "channel[%p]", - aChannel)); - nsCOMPtr httpChannel = do_QueryInterface(aChannel); - if (httpChannel) { - Unused << httpChannel->CancelByChannelClassifier(NS_ERROR_TRACKING_URI); - } else { - Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI); + UC_LOG( + ("UrlClassifierFeatureTrackingProtection::ProcessChannel, cancelling " + "channel[%p]", + aChannel)); + nsCOMPtr httpChannel = do_QueryInterface(aChannel); + if (httpChannel) { + Unused << httpChannel->CancelByChannelClassifier(NS_ERROR_TRACKING_URI); + } else { + Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI); + } } return NS_OK;