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:
Ehsan Akhgari 2019-02-28 15:29:10 +00:00
Родитель fa6f4e4e2b
Коммит cfb1b88614
8 изменённых файлов: 167 добавлений и 136 удалений

Просмотреть файл

@ -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;