mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
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:
parent
c39dc7f1aa
commit
fcf2cc8123
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -58,10 +58,6 @@ class UrlClassifierFeatureBase : public nsIUrlClassifierFeature,
|
||||
void InitializePreferences();
|
||||
void ShutdownPreferences();
|
||||
|
||||
bool IsAllowListed(
|
||||
nsIChannel* aChannel,
|
||||
AntiTrackingCommon::ContentBlockingAllowListPurpose aPurpose);
|
||||
|
||||
private:
|
||||
nsCString mName;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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()) {
|
||||
|
@ -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
|
@ -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
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -34,6 +34,7 @@ UNIFIED_SOURCES += [
|
||||
'UrlClassifierFeatureCryptominingProtection.cpp',
|
||||
'UrlClassifierFeatureCustomTables.cpp',
|
||||
'UrlClassifierFeatureFactory.cpp',
|
||||
'UrlClassifierFeatureFingerprintingAnnotation.cpp',
|
||||
'UrlClassifierFeatureFingerprintingProtection.cpp',
|
||||
'UrlClassifierFeatureFlash.cpp',
|
||||
'UrlClassifierFeatureLoginReputation.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user