зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1525458 - Part 1: Only emit the loaded events for various content blocking categories in the presence of an allow-list entry for the top-level document when content would have been blocked otherwise; r=baku,dimi
Previously the code here used to emit the loaded events for every resource examined by the URL Classifier Features (in other words, every third party resource). But we only need to emit the events in cases where without the presence of the allow-list we would have blocked the content. Differential Revision: https://phabricator.services.mozilla.com/D20874 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
fa6f4e4e2b
Коммит
cfb1b88614
|
@ -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<nsIHttpChannelInternal> channel = do_QueryInterface(aChannel);
|
||||
if (!channel) {
|
||||
UC_LOG(("nsChannelClassifier: Not an HTTP channel"));
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> chanURI;
|
||||
nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
|
||||
|
@ -112,86 +101,31 @@ UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
|
|||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIIOService> ios = services::GetIOService();
|
||||
if (NS_WARN_IF(!ios)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> 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<nsIURI> topWinURI;
|
||||
nsCOMPtr<nsIHttpChannelInternal> 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()));
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<nsIHttpChannelInternal> channel = do_QueryInterface(aChannel);
|
||||
if (!channel) {
|
||||
UC_LOG(("nsChannelClassifier: Not an HTTP channel"));
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> 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<nsIIOService> 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<nsIURI> 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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<nsIHttpChannelInternal> 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<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
|
||||
|
||||
if (httpChannel) {
|
||||
Unused << httpChannel->CancelByChannelClassifier(
|
||||
NS_ERROR_CRYPTOMINING_URI);
|
||||
} else {
|
||||
Unused << aChannel->Cancel(NS_ERROR_CRYPTOMINING_URI);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -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<nsIHttpChannelInternal> 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<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
|
||||
|
||||
if (httpChannel) {
|
||||
Unused << httpChannel->CancelByChannelClassifier(
|
||||
NS_ERROR_FINGERPRINTING_URI);
|
||||
} else {
|
||||
Unused << aChannel->Cancel(NS_ERROR_FINGERPRINTING_URI);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<nsIHttpChannelInternal> 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<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
|
||||
if (httpChannel) {
|
||||
Unused << httpChannel->CancelByChannelClassifier(NS_ERROR_TRACKING_URI);
|
||||
} else {
|
||||
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче