Bug 1533074 - Implement Fingerprinting and Cryptomining annotation features - Part 2 - Fingerprinting-annotation, r=dimi

Differential Revision: https://phabricator.services.mozilla.com/D22342

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrea Marchesini 2019-03-14 17:48:20 +00:00
parent c39dc7f1aa
commit fcf2cc8123
16 changed files with 473 additions and 213 deletions

View File

@ -1248,6 +1248,7 @@ pref("services.sync.prefs.sync.privacy.sanitize.sanitizeOnShutdown", true);
pref("services.sync.prefs.sync.privacy.trackingprotection.enabled", true);
pref("services.sync.prefs.sync.privacy.trackingprotection.cryptomining.enabled", true);
pref("services.sync.prefs.sync.privacy.trackingprotection.fingerprinting.enabled", true);
pref("services.sync.prefs.sync.privacy.trackingprotection.fingerprinting.annotate.enabled", true);
pref("services.sync.prefs.sync.privacy.trackingprotection.pbmode.enabled", true);
pref("services.sync.prefs.sync.privacy.resistFingerprinting", true);
pref("services.sync.prefs.sync.privacy.reduceTimerPrecision", true);

View File

@ -2007,13 +2007,18 @@ VARCACHE_PREF(
)
// Block 3rd party fingerprinting resources.
# define PREF_VALUE false
VARCACHE_PREF(
"privacy.trackingprotection.fingerprinting.enabled",
privacy_trackingprotection_fingerprinting_enabled,
bool, PREF_VALUE
bool, false
)
// Annotate fingerprinting resources.
VARCACHE_PREF(
"privacy.trackingprotection.fingerprinting.annotate.enabled",
privacy_trackingprotection_fingerprinting_annotate_enabled,
bool, false
)
#undef PREF_VALUE
// Block 3rd party cryptomining resources.
# define PREF_VALUE false

View File

@ -64,6 +64,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/Move.h"
#include "mozilla/net/PartiallySeekableInputStream.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/InputStreamLengthHelper.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsIMIMEInputStream.h"
@ -1474,9 +1475,10 @@ bool
HttpBaseChannel::IsTrackingResource() const {
MOZ_ASSERT(!mFirstPartyClassificationFlags ||
!mThirdPartyClassificationFlags);
return
(mThirdPartyClassificationFlags & nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING) ||
(mFirstPartyClassificationFlags & nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING);
return UrlClassifierCommon::IsTrackingClassificationFlag(
mThirdPartyClassificationFlags) ||
UrlClassifierCommon::IsTrackingClassificationFlag(
mFirstPartyClassificationFlags);
}
NS_IMETHODIMP
@ -1489,7 +1491,8 @@ bool
HttpBaseChannel::IsThirdPartyTrackingResource() const {
MOZ_ASSERT(
!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags));
return (mThirdPartyClassificationFlags & nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING);
return UrlClassifierCommon::IsTrackingClassificationFlag(
mThirdPartyClassificationFlags);
}
NS_IMETHODIMP

View File

@ -542,7 +542,8 @@ interface nsIHttpChannel : nsIChannel
* 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)
* (classificationFlags & CLASSIFIED_TRACKING) ||
* (classificationFlags & CLASSIFIED_FINGERPRINTING)
*
* Note that top-level channels could be marked as tracking
* resource. In order to identify third-party tracking resources
@ -556,7 +557,8 @@ interface nsIHttpChannel : nsIChannel
* window URI.
*
* This is a helper attribute which returns the same value of
* (thirdPartyClassificationFlags & CLASSIFIED_TRACKING)
* (thirdPartyClassificationFlags & CLASSIFIED_TRACKING) ||
* (thirdPartyClassificationFlags & CLASSIFIED_FINGERPRINTING)
*/
[infallible] readonly attribute boolean isThirdPartyTrackingResource;

View File

@ -8,6 +8,7 @@
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/net/HttpBaseChannel.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/StaticPrefs.h"
#include "mozIThirdPartyUtil.h"
@ -22,6 +23,8 @@
#include "nsIScriptError.h"
#include "nsIWebProgressListener.h"
#include "nsNetUtil.h"
#include "nsQueryObject.h"
#include "TrackingDummyChannel.h"
namespace mozilla {
namespace net {
@ -275,5 +278,188 @@ nsresult UrlClassifierCommon::CreatePairwiseWhiteListURI(nsIChannel* aChannel,
return NS_OK;
}
namespace {
void SetClassificationFlagsHelper(nsIChannel* aChannel,
uint32_t aClassificationFlags,
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->NotifyClassificationFlags(aClassificationFlags,
aIsThirdParty);
}
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
if (httpChannel) {
httpChannel->AddClassificationFlags(aClassificationFlags, aIsThirdParty);
}
RefPtr<TrackingDummyChannel> dummyChannel = do_QueryObject(aChannel);
if (dummyChannel) {
dummyChannel->AddClassificationFlags(aClassificationFlags);
}
}
void LowerPriorityHelper(nsIChannel* aChannel) {
MOZ_ASSERT(aChannel);
bool isBlockingResource = false;
nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(aChannel));
if (cos) {
if (nsContentUtils::IsTailingEnabled()) {
uint32_t cosFlags = 0;
cos->GetClassFlags(&cosFlags);
isBlockingResource =
cosFlags & (nsIClassOfService::UrgentStart |
nsIClassOfService::Leader | nsIClassOfService::Unblocked);
// Requests not allowed to be tailed are usually those with higher
// prioritization. That overweights being a tracker: don't throttle
// them when not in background.
if (!(cosFlags & nsIClassOfService::TailForbidden)) {
cos->AddClassFlags(nsIClassOfService::Throttleable);
}
} else {
// Yes, we even don't want to evaluate the isBlockingResource when tailing
// is off see bug 1395525.
cos->AddClassFlags(nsIClassOfService::Throttleable);
}
}
if (!isBlockingResource) {
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(aChannel);
if (p) {
if (UC_LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetAsciiSpec(spec);
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(("Setting PRIORITY_LOWEST for channel[%p] (%s)", aChannel,
spec.get()));
}
p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
}
}
}
} // namespace
// static
void UrlClassifierCommon::AnnotateChannel(
nsIChannel* aChannel,
AntiTrackingCommon::ContentBlockingAllowListPurpose aPurpose,
uint32_t aClassificationFlags, uint32_t aLoadingState) {
MOZ_ASSERT(aChannel);
MOZ_ASSERT(aPurpose == AntiTrackingCommon::eTrackingProtection ||
aPurpose == AntiTrackingCommon::eTrackingAnnotations ||
aPurpose == AntiTrackingCommon::eFingerprinting ||
aPurpose == AntiTrackingCommon::eCryptomining);
nsCOMPtr<nsIURI> chanURI;
nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
UC_LOG(
("UrlClassifierCommon::AnnotateChannel nsIChannel::GetURI(%p) failed",
(void*)aChannel));
return;
}
bool isThirdPartyWithTopLevelWinURI =
nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel, chanURI);
UC_LOG(("UrlClassifierCommon::AnnotateChannel, annotating channel[%p]",
aChannel));
SetClassificationFlagsHelper(aChannel, aClassificationFlags,
isThirdPartyWithTopLevelWinURI);
if (isThirdPartyWithTopLevelWinURI || IsAllowListed(aChannel, aPurpose)) {
UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
aChannel, aLoadingState);
}
if (isThirdPartyWithTopLevelWinURI &&
StaticPrefs::privacy_trackingprotection_lower_network_priority()) {
LowerPriorityHelper(aChannel);
}
}
// static
bool UrlClassifierCommon::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;
}
// static
bool UrlClassifierCommon::IsTrackingClassificationFlag(uint32_t aFlag) {
return (aFlag & nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING) ||
(aFlag &
nsIHttpChannel::ClassificationFlags::CLASSIFIED_FINGERPRINTING);
}
} // namespace net
} // namespace mozilla

View File

@ -42,6 +42,17 @@ class UrlClassifierCommon final {
static nsresult CreatePairwiseWhiteListURI(nsIChannel* aChannel,
nsIURI** aURI);
static void AnnotateChannel(
nsIChannel* aChannel,
AntiTrackingCommon::ContentBlockingAllowListPurpose aPurpose,
uint32_t aClassificationFlags, uint32_t aLoadingState);
static bool IsAllowListed(
nsIChannel* aChannel,
AntiTrackingCommon::ContentBlockingAllowListPurpose aPurpose);
static bool IsTrackingClassificationFlag(uint32_t aFlag);
private:
// aBlockedReason must be one of the nsIWebProgressListener state.
static void NotifyChannelBlocked(nsIChannel* aChannel,

View File

@ -164,65 +164,5 @@ 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

View File

@ -58,10 +58,6 @@ class UrlClassifierFeatureBase : public nsIUrlClassifierFeature,
void InitializePreferences();
void ShutdownPreferences();
bool IsAllowListed(
nsIChannel* aChannel,
AntiTrackingCommon::ContentBlockingAllowListPurpose aPurpose);
private:
nsCString mName;

View File

@ -143,8 +143,8 @@ UrlClassifierFeatureCryptominingProtection::ProcessChannel(
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aShouldContinue);
bool isAllowListed =
IsAllowListed(aChannel, AntiTrackingCommon::eCryptomining);
bool isAllowListed = UrlClassifierCommon::IsAllowListed(
aChannel, AntiTrackingCommon::eCryptomining);
// This is a blocking feature.
*aShouldContinue = isAllowListed;

View File

@ -8,6 +8,7 @@
// List of Features
#include "UrlClassifierFeatureCryptominingProtection.h"
#include "UrlClassifierFeatureFingerprintingAnnotation.h"
#include "UrlClassifierFeatureFingerprintingProtection.h"
#include "UrlClassifierFeatureFlash.h"
#include "UrlClassifierFeatureLoginReputation.h"
@ -29,6 +30,7 @@ void UrlClassifierFeatureFactory::Shutdown() {
}
UrlClassifierFeatureCryptominingProtection::MaybeShutdown();
UrlClassifierFeatureFingerprintingAnnotation::MaybeShutdown();
UrlClassifierFeatureFingerprintingProtection::MaybeShutdown();
UrlClassifierFeatureFlash::MaybeShutdown();
UrlClassifierFeatureLoginReputation::MaybeShutdown();
@ -63,6 +65,12 @@ void UrlClassifierFeatureFactory::GetFeaturesFromChannel(
aFeatures.AppendElement(feature);
}
// Fingerprinting Annotation
feature = UrlClassifierFeatureFingerprintingAnnotation::MaybeCreate(aChannel);
if (feature) {
aFeatures.AppendElement(feature);
}
// Tracking Protection
feature = UrlClassifierFeatureTrackingProtection::MaybeCreate(aChannel);
if (feature) {
@ -108,6 +116,13 @@ UrlClassifierFeatureFactory::GetFeatureByName(const nsACString& aName) {
return feature.forget();
}
// Fingerprinting Annotation
feature =
UrlClassifierFeatureFingerprintingAnnotation::GetIfNameMatches(aName);
if (feature) {
return feature.forget();
}
// Fingerprinting Protection
feature =
UrlClassifierFeatureFingerprintingProtection::GetIfNameMatches(aName);
@ -161,6 +176,12 @@ void UrlClassifierFeatureFactory::GetFeatureNames(nsTArray<nsCString>& aArray) {
aArray.AppendElement(name);
}
// Fingerprinting Annotation
name.Assign(UrlClassifierFeatureFingerprintingAnnotation::Name());
if (!name.IsEmpty()) {
aArray.AppendElement(name);
}
// Fingerprinting Protection
name.Assign(UrlClassifierFeatureFingerprintingProtection::Name());
if (!name.IsEmpty()) {

View File

@ -0,0 +1,160 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "UrlClassifierFeatureFingerprintingAnnotation.h"
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/StaticPrefs.h"
#include "nsContentUtils.h"
#include "nsNetUtil.h"
namespace mozilla {
namespace net {
namespace {
#define FINGERPRINTING_ANNOTATION_FEATURE_NAME "fingerprinting-annotation"
#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST \
"urlclassifier.features.fingerprinting.annotate.blacklistTables"
#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST_TEST_ENTRIES \
"urlclassifier.features.fingerprinting.annotate.blacklistHosts"
#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST \
"urlclassifier.features.fingerprinting.annotate.whitelistTables"
#define URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST_TEST_ENTRIES \
"urlclassifier.features.fingerprinting.annotate.whitelistHosts"
#define TABLE_FINGERPRINTING_ANNOTATION_BLACKLIST_PREF \
"fingerprinting-annotate-blacklist-pref"
#define TABLE_FINGERPRINTING_ANNOTATION_WHITELIST_PREF \
"fingerprinting-annotate-whitelist-pref"
StaticRefPtr<UrlClassifierFeatureFingerprintingAnnotation>
gFeatureFingerprintingAnnotation;
} // namespace
UrlClassifierFeatureFingerprintingAnnotation::
UrlClassifierFeatureFingerprintingAnnotation()
: UrlClassifierFeatureBase(
NS_LITERAL_CSTRING(FINGERPRINTING_ANNOTATION_FEATURE_NAME),
NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST),
NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST),
NS_LITERAL_CSTRING(
URLCLASSIFIER_FINGERPRINTING_ANNOTATION_BLACKLIST_TEST_ENTRIES),
NS_LITERAL_CSTRING(
URLCLASSIFIER_FINGERPRINTING_ANNOTATION_WHITELIST_TEST_ENTRIES),
NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_ANNOTATION_BLACKLIST_PREF),
NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_ANNOTATION_WHITELIST_PREF),
EmptyCString()) {}
/* static */ const char* UrlClassifierFeatureFingerprintingAnnotation::Name() {
return FINGERPRINTING_ANNOTATION_FEATURE_NAME;
}
/* static */
void UrlClassifierFeatureFingerprintingAnnotation::MaybeInitialize() {
UC_LOG(("UrlClassifierFeatureFingerprintingAnnotation: MaybeInitialize"));
if (!gFeatureFingerprintingAnnotation) {
gFeatureFingerprintingAnnotation =
new UrlClassifierFeatureFingerprintingAnnotation();
gFeatureFingerprintingAnnotation->InitializePreferences();
}
}
/* static */
void UrlClassifierFeatureFingerprintingAnnotation::MaybeShutdown() {
UC_LOG(("UrlClassifierFeatureFingerprintingAnnotation: MaybeShutdown"));
if (gFeatureFingerprintingAnnotation) {
gFeatureFingerprintingAnnotation->ShutdownPreferences();
gFeatureFingerprintingAnnotation = nullptr;
}
}
/* static */
already_AddRefed<UrlClassifierFeatureFingerprintingAnnotation>
UrlClassifierFeatureFingerprintingAnnotation::MaybeCreate(
nsIChannel* aChannel) {
MOZ_ASSERT(aChannel);
UC_LOG(
("UrlClassifierFeatureFingerprintingAnnotation: MaybeCreate for channel "
"%p",
aChannel));
if (!StaticPrefs::
privacy_trackingprotection_fingerprinting_annotate_enabled()) {
return nullptr;
}
if (!UrlClassifierCommon::ShouldEnableClassifier(aChannel)) {
return nullptr;
}
MaybeInitialize();
MOZ_ASSERT(gFeatureFingerprintingAnnotation);
RefPtr<UrlClassifierFeatureFingerprintingAnnotation> self =
gFeatureFingerprintingAnnotation;
return self.forget();
}
/* static */
already_AddRefed<nsIUrlClassifierFeature>
UrlClassifierFeatureFingerprintingAnnotation::GetIfNameMatches(
const nsACString& aName) {
if (!aName.EqualsLiteral(FINGERPRINTING_ANNOTATION_FEATURE_NAME)) {
return nullptr;
}
MaybeInitialize();
MOZ_ASSERT(gFeatureFingerprintingAnnotation);
RefPtr<UrlClassifierFeatureFingerprintingAnnotation> self =
gFeatureFingerprintingAnnotation;
return self.forget();
}
NS_IMETHODIMP
UrlClassifierFeatureFingerprintingAnnotation::ProcessChannel(
nsIChannel* aChannel, const nsACString& aList, bool* aShouldContinue) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aShouldContinue);
// This is not a blocking feature.
*aShouldContinue = true;
UC_LOG(
("UrlClassifierFeatureFingerprintingAnnotation::ProcessChannel, "
"annotating channel[%p]",
aChannel));
UrlClassifierCommon::AnnotateChannel(
aChannel, AntiTrackingCommon::eFingerprinting,
nsIHttpChannel::ClassificationFlags::CLASSIFIED_FINGERPRINTING,
nsIWebProgressListener::STATE_LOADED_FINGERPRINTING_CONTENT);
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureFingerprintingAnnotation::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aURI);
if (aListType == nsIUrlClassifierFeature::blacklist) {
return aChannel->GetURI(aURI);
}
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
}
} // namespace net
} // namespace mozilla

View File

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_net_UrlClassifierFeatureFingerprintingAnnotation_h
#define mozilla_net_UrlClassifierFeatureFingerprintingAnnotation_h
#include "UrlClassifierFeatureBase.h"
class nsIChannel;
namespace mozilla {
namespace net {
class UrlClassifierFeatureFingerprintingAnnotation final
: public UrlClassifierFeatureBase {
public:
static const char* Name();
static void MaybeShutdown();
static already_AddRefed<UrlClassifierFeatureFingerprintingAnnotation>
MaybeCreate(nsIChannel* aChannel);
static already_AddRefed<nsIUrlClassifierFeature> GetIfNameMatches(
const nsACString& aName);
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override;
private:
UrlClassifierFeatureFingerprintingAnnotation();
static void MaybeInitialize();
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_UrlClassifierFeatureFingerprintingAnnotation_h

View File

@ -17,7 +17,7 @@ namespace net {
namespace {
#define FINGERPRINTING_FEATURE_NAME "fingerprinting"
#define FINGERPRINTING_FEATURE_NAME "fingerprinting-protection"
#define URLCLASSIFIER_FINGERPRINTING_BLACKLIST \
"urlclassifier.features.fingerprinting.blacklistTables"
@ -147,38 +147,31 @@ UrlClassifierFeatureFingerprintingProtection::ProcessChannel(
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aShouldContinue);
bool isAllowListed =
IsAllowListed(aChannel, AntiTrackingCommon::eFingerprinting);
bool isAllowListed = UrlClassifierCommon::IsAllowListed(
aChannel, AntiTrackingCommon::eFingerprinting);
// This is a blocking feature.
*aShouldContinue = isAllowListed;
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);
return NS_OK;
}
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_FINGERPRINTING_URI,
aList, EmptyCString(), EmptyCString());
UC_LOG(
("UrlClassifierFeatureFingerprintingProtection::ProcessChannel, "
"cancelling "
"channel[%p]",
aChannel));
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
if (httpChannel) {
Unused << httpChannel->CancelByChannelClassifier(
NS_ERROR_FINGERPRINTING_URI);
} else {
UrlClassifierCommon::SetBlockedContent(aChannel,
NS_ERROR_FINGERPRINTING_URI, aList,
EmptyCString(), EmptyCString());
UC_LOG(
("UrlClassifierFeatureFingerprintingProtection::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);
}
Unused << aChannel->Cancel(NS_ERROR_FINGERPRINTING_URI);
}
return NS_OK;

View File

@ -8,13 +8,10 @@
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/Logging.h"
#include "mozilla/net/HttpBaseChannel.h"
#include "mozilla/StaticPrefs.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "nsContentUtils.h"
#include "nsQueryObject.h"
#include "TrackingDummyChannel.h"
namespace mozilla {
namespace net {
@ -38,76 +35,6 @@ namespace {
StaticRefPtr<UrlClassifierFeatureTrackingAnnotation> gFeatureTrackingAnnotation;
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->NotifyClassificationFlags(
nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING, aIsThirdParty);
}
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
if (httpChannel) {
httpChannel->AddClassificationFlags(nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING,
aIsThirdParty);
}
RefPtr<TrackingDummyChannel> dummyChannel = do_QueryObject(aChannel);
if (dummyChannel) {
dummyChannel->AddClassificationFlags(nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING);
}
}
static void LowerPriorityHelper(nsIChannel* aChannel) {
MOZ_ASSERT(aChannel);
bool isBlockingResource = false;
nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(aChannel));
if (cos) {
if (nsContentUtils::IsTailingEnabled()) {
uint32_t cosFlags = 0;
cos->GetClassFlags(&cosFlags);
isBlockingResource =
cosFlags & (nsIClassOfService::UrgentStart |
nsIClassOfService::Leader | nsIClassOfService::Unblocked);
// Requests not allowed to be tailed are usually those with higher
// prioritization. That overweights being a tracker: don't throttle
// them when not in background.
if (!(cosFlags & nsIClassOfService::TailForbidden)) {
cos->AddClassFlags(nsIClassOfService::Throttleable);
}
} else {
// Yes, we even don't want to evaluate the isBlockingResource when tailing
// is off see bug 1395525.
cos->AddClassFlags(nsIClassOfService::Throttleable);
}
}
if (!isBlockingResource) {
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(aChannel);
if (p) {
if (UC_LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetAsciiSpec(spec);
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(("Setting PRIORITY_LOWEST for channel[%p] (%s)", aChannel,
spec.get()));
}
p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
}
}
}
} // namespace
@ -197,42 +124,10 @@ UrlClassifierFeatureTrackingAnnotation::ProcessChannel(nsIChannel* aChannel,
// This is not a blocking feature.
*aShouldContinue = true;
nsCOMPtr<nsIURI> chanURI;
nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
UC_LOG(
("UrlClassifierFeatureTrackingAnnotation::ProcessChannel "
"nsIChannel::GetURI(%p) failed",
(void*)aChannel));
return NS_OK;
}
bool isThirdPartyWithTopLevelWinURI =
nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel, chanURI);
bool isAllowListed =
IsAllowListed(aChannel, AntiTrackingCommon::eTrackingAnnotations);
UC_LOG(
("UrlClassifierFeatureTrackingAnnotation::ProcessChannel, annotating "
"channel[%p]",
aChannel));
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);
}
if (isThirdPartyWithTopLevelWinURI &&
StaticPrefs::privacy_trackingprotection_lower_network_priority()) {
LowerPriorityHelper(aChannel);
}
UrlClassifierCommon::AnnotateChannel(
aChannel, AntiTrackingCommon::eTrackingAnnotations,
nsIHttpChannel::ClassificationFlags::CLASSIFIED_TRACKING,
nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT);
return NS_OK;
}

View File

@ -139,8 +139,8 @@ UrlClassifierFeatureTrackingProtection::ProcessChannel(nsIChannel* aChannel,
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aShouldContinue);
bool isAllowListed =
IsAllowListed(aChannel, AntiTrackingCommon::eTrackingProtection);
bool isAllowListed = UrlClassifierCommon::IsAllowListed(
aChannel, AntiTrackingCommon::eTrackingProtection);
// This is a blocking feature.
*aShouldContinue = isAllowListed;

View File

@ -34,6 +34,7 @@ UNIFIED_SOURCES += [
'UrlClassifierFeatureCryptominingProtection.cpp',
'UrlClassifierFeatureCustomTables.cpp',
'UrlClassifierFeatureFactory.cpp',
'UrlClassifierFeatureFingerprintingAnnotation.cpp',
'UrlClassifierFeatureFingerprintingProtection.cpp',
'UrlClassifierFeatureFlash.cpp',
'UrlClassifierFeatureLoginReputation.cpp',