mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Backed out 3 changesets (bug 1844558, bug 1894040) for causing build bustages on BounceTrackingProtection.cpp . CLOSED TREE
Backed out changeset 00cce862553d (bug 1844558) Backed out changeset 3fcb5ea142fd (bug 1894040) Backed out changeset aa731ff97ebd (bug 1894040)
This commit is contained in:
parent
ef34fc3422
commit
c284a53117
@ -162,9 +162,6 @@ var allowlist = [
|
||||
// toolkit/mozapps/extensions/AddonContentPolicy.cpp
|
||||
{ file: "resource://gre/localization/en-US/toolkit/global/cspErrors.ftl" },
|
||||
|
||||
// toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.cpp
|
||||
{ file: "resource://gre/localization/en-US/toolkit/global/antiTracking.ftl" },
|
||||
|
||||
// The l10n build system can't package string files only for some platforms.
|
||||
{
|
||||
file: "resource://gre/chrome/en-US/locale/en-US/global-platform/mac/accessible.properties",
|
||||
|
@ -178,10 +178,6 @@ BrowsingContextWebProgress::GetBounceTrackingState() {
|
||||
return do_AddRef(mBounceTrackingState);
|
||||
}
|
||||
|
||||
void BrowsingContextWebProgress::DropBounceTrackingState() {
|
||||
mBounceTrackingState = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIWebProgressListener
|
||||
|
||||
|
@ -64,10 +64,6 @@ class BrowsingContextWebProgress final : public nsIWebProgress,
|
||||
|
||||
already_AddRefed<BounceTrackingState> GetBounceTrackingState();
|
||||
|
||||
// Drops our reference to BounceTrackingState. This is used when the feature
|
||||
// gets disabled.
|
||||
void DropBounceTrackingState();
|
||||
|
||||
private:
|
||||
virtual ~BrowsingContextWebProgress();
|
||||
|
||||
|
@ -14789,17 +14789,11 @@
|
||||
value: ""
|
||||
mirror: never
|
||||
|
||||
# Controls Bounce Tracking Protection behavior.
|
||||
# Set to 0 to fully disable. See nsIBounceTrackingProtection.idl for
|
||||
# documentation.
|
||||
- name: privacy.bounceTrackingProtection.mode
|
||||
type: uint32_t
|
||||
#ifdef NIGHTLY_BUILD
|
||||
value: 1
|
||||
#else
|
||||
value: 3
|
||||
#endif
|
||||
mirror: always
|
||||
# Main pref to enable / disable the feature.
|
||||
- name: privacy.bounceTrackingProtection.enabled
|
||||
type: bool
|
||||
value: true
|
||||
mirror: once
|
||||
|
||||
# How long to wait for a client redirect after a navigation ends.
|
||||
- name: privacy.bounceTrackingProtection.clientBounceDetectionTimerPeriodMS
|
||||
@ -14833,6 +14827,14 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Enables a mode where if bounce tracking protection is enabled it classifies
|
||||
# but does not purge trackers. This mode is helpful for testing the feature
|
||||
# without risking data loss. Telemetry is still collected normally.
|
||||
- name: privacy.bounceTrackingProtection.enableDryRunMode
|
||||
type: bool
|
||||
value: @IS_NOT_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
||||
# To be used in automated test environments to enable observer messages.
|
||||
- name: privacy.bounceTrackingProtection.enableTestMode
|
||||
type: bool
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "mozilla/intl/Localization.h"
|
||||
|
||||
#define TEST_OBSERVER_MSG_RECORD_BOUNCES_FINISHED "test-record-bounces-finished"
|
||||
|
||||
@ -59,8 +57,6 @@ static bool sInitFailed = false;
|
||||
// Initialized on first call of GetSingleton.
|
||||
Maybe<bool> BounceTrackingProtection::sFeatureIsEnabled;
|
||||
|
||||
static const char kBTPModePref[] = "privacy.bounceTrackingProtection.mode";
|
||||
|
||||
static constexpr uint32_t TRACKER_PURGE_FLAGS =
|
||||
nsIClearDataService::CLEAR_ALL_CACHES | nsIClearDataService::CLEAR_COOKIES |
|
||||
nsIClearDataService::CLEAR_DOM_STORAGES |
|
||||
@ -82,8 +78,13 @@ BounceTrackingProtection::GetSingleton() {
|
||||
|
||||
// First call to GetSingleton, check main feature pref and record telemetry.
|
||||
if (sFeatureIsEnabled.isNothing()) {
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_DISABLED) {
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_enabled_AtStartup()) {
|
||||
sFeatureIsEnabled = Some(true);
|
||||
|
||||
glean::bounce_tracking_protection::enabled_at_startup.Set(true);
|
||||
glean::bounce_tracking_protection::enabled_dry_run_mode_at_startup.Set(
|
||||
StaticPrefs::privacy_bounceTrackingProtection_enableDryRunMode());
|
||||
} else {
|
||||
sFeatureIsEnabled = Some(false);
|
||||
|
||||
glean::bounce_tracking_protection::enabled_at_startup.Set(false);
|
||||
@ -93,12 +94,6 @@ BounceTrackingProtection::GetSingleton() {
|
||||
// Feature is disabled.
|
||||
return nullptr;
|
||||
}
|
||||
sFeatureIsEnabled = Some(true);
|
||||
|
||||
glean::bounce_tracking_protection::enabled_at_startup.Set(true);
|
||||
glean::bounce_tracking_protection::enabled_dry_run_mode_at_startup.Set(
|
||||
StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN);
|
||||
}
|
||||
MOZ_ASSERT(sFeatureIsEnabled.isSome());
|
||||
|
||||
@ -129,17 +124,14 @@ BounceTrackingProtection::GetSingleton() {
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtection::Init() {
|
||||
MOZ_ASSERT(StaticPrefs::privacy_bounceTrackingProtection_mode() !=
|
||||
nsIBounceTrackingProtection::MODE_DISABLED,
|
||||
"Mode pref must have an enabled state for init to be called.");
|
||||
MOZ_LOG(
|
||||
gBounceTrackingProtectionLog, LogLevel::Info,
|
||||
("Init BounceTrackingProtection. Config: mode: %d, "
|
||||
("Init BounceTrackingProtection. Config: enableDryRunMode: %d, "
|
||||
"bounceTrackingActivationLifetimeSec: %d, bounceTrackingGracePeriodSec: "
|
||||
"%d, bounceTrackingPurgeTimerPeriodSec: %d, "
|
||||
"clientBounceDetectionTimerPeriodMS: %d, requireStatefulBounces: %d, "
|
||||
"HasMigratedUserActivationData: %d",
|
||||
StaticPrefs::privacy_bounceTrackingProtection_mode(),
|
||||
StaticPrefs::privacy_bounceTrackingProtection_enableDryRunMode(),
|
||||
StaticPrefs::
|
||||
privacy_bounceTrackingProtection_bounceTrackingActivationLifetimeSec(),
|
||||
StaticPrefs::
|
||||
@ -163,31 +155,6 @@ nsresult BounceTrackingProtection::Init() {
|
||||
("user activation permission migration failed"));
|
||||
}
|
||||
|
||||
// Register feature pref listener which dynamically enables or disables the
|
||||
// feature depending on feature pref state.
|
||||
rv = Preferences::RegisterCallback(&BounceTrackingProtection::OnPrefChange,
|
||||
kBTPModePref);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Run the remaining init logic.
|
||||
return OnModeChange(true);
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtection::UpdateBounceTrackingPurgeTimer(
|
||||
bool aShouldEnable) {
|
||||
// Cancel the existing timer.
|
||||
// If disabling: we're done now.
|
||||
// If enabling: schedule a new timer so interval changes (as controlled by the
|
||||
// pref) are taken into account.
|
||||
if (mBounceTrackingPurgeTimer) {
|
||||
mBounceTrackingPurgeTimer->Cancel();
|
||||
mBounceTrackingPurgeTimer = nullptr;
|
||||
}
|
||||
|
||||
if (!aShouldEnable) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Schedule timer for tracker purging. The timer interval is determined by
|
||||
// pref.
|
||||
uint32_t purgeTimerPeriod = StaticPrefs::
|
||||
@ -221,82 +188,6 @@ nsresult BounceTrackingProtection::UpdateBounceTrackingPurgeTimer(
|
||||
"mBounceTrackingPurgeTimer");
|
||||
}
|
||||
|
||||
// static
|
||||
void BounceTrackingProtection::OnPrefChange(const char* aPref, void* aData) {
|
||||
MOZ_ASSERT(sBounceTrackingProtection);
|
||||
MOZ_ASSERT(strcmp(kBTPModePref, aPref) == 0);
|
||||
sBounceTrackingProtection->OnModeChange(false);
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtection::OnModeChange(bool aIsStartup) {
|
||||
// Get feature mode from pref and ensure its within bounds.
|
||||
uint8_t modeInt = StaticPrefs::privacy_bounceTrackingProtection_mode();
|
||||
NS_ENSURE_TRUE(
|
||||
modeInt >= 0 && modeInt <= nsIBounceTrackingProtection::MAX_MODE_VALUE,
|
||||
NS_ERROR_FAILURE);
|
||||
nsIBounceTrackingProtection::Modes mode =
|
||||
static_cast<nsIBounceTrackingProtection::Modes>(modeInt);
|
||||
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug,
|
||||
("%s: mode: %d.", __FUNCTION__, mode));
|
||||
if (sInitFailed) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (!aIsStartup) {
|
||||
// Clear bounce tracker candidate map for any mode change so it's not leaked
|
||||
// into other modes. For example if we switch from dry-run mode into fully
|
||||
// enabled we want a clean slate to not purge trackers that we've classified
|
||||
// in dry-run mode. User activation data must be kept to avoid false
|
||||
// positives.
|
||||
MOZ_ASSERT(mStorage);
|
||||
result = mStorage->ClearByType(
|
||||
BounceTrackingProtectionStorage::EntryType::BounceTracker);
|
||||
}
|
||||
|
||||
// On disable
|
||||
if (mode == nsIBounceTrackingProtection::MODE_DISABLED ||
|
||||
mode == nsIBounceTrackingProtection::MODE_ENABLED_STANDBY) {
|
||||
// No further cleanup needed if we're just starting up.
|
||||
if (aIsStartup) {
|
||||
MOZ_ASSERT(!mStorageObserver);
|
||||
MOZ_ASSERT(!mBounceTrackingPurgeTimer);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Destroy storage observer to stop receiving storage notifications.
|
||||
mStorageObserver = nullptr;
|
||||
|
||||
// Stop regular purging.
|
||||
nsresult rv = UpdateBounceTrackingPurgeTimer(false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
result = rv;
|
||||
// Even if this step fails try to do more cleanup.
|
||||
}
|
||||
|
||||
// Clear all per-tab state.
|
||||
BounceTrackingState::DestroyAll();
|
||||
return result;
|
||||
}
|
||||
|
||||
// On enable
|
||||
MOZ_ASSERT(mode == nsIBounceTrackingProtection::MODE_ENABLED ||
|
||||
mode == nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN);
|
||||
|
||||
// Create and init storage observer.
|
||||
mStorageObserver = new BounceTrackingStorageObserver();
|
||||
nsresult rv = mStorageObserver->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Schedule regular purging.
|
||||
rv = UpdateBounceTrackingPurgeTimer(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtection::RecordStatefulBounces(
|
||||
BounceTrackingState* aBounceTrackingState) {
|
||||
NS_ENSURE_ARG_POINTER(aBounceTrackingState);
|
||||
@ -315,8 +206,6 @@ nsresult BounceTrackingProtection::RecordStatefulBounces(
|
||||
mStorage->GetOrCreateStateGlobal(aBounceTrackingState);
|
||||
MOZ_ASSERT(globalState);
|
||||
|
||||
nsTArray<nsCString> classifiedHosts;
|
||||
|
||||
// For each host in navigable’s bounce tracking record's bounce set:
|
||||
for (const nsACString& host : record->GetBounceHosts()) {
|
||||
// Skip "null" entries, they are only used for logging purposes.
|
||||
@ -376,8 +265,6 @@ nsresult BounceTrackingProtection::RecordStatefulBounces(
|
||||
continue;
|
||||
}
|
||||
|
||||
classifiedHosts.AppendElement(host);
|
||||
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Info,
|
||||
("%s: Added bounce tracker candidate. siteHost: %s, "
|
||||
"aBounceTrackingState: %s",
|
||||
@ -391,11 +278,6 @@ nsresult BounceTrackingProtection::RecordStatefulBounces(
|
||||
("%s: Done, reset aBounceTrackingState: %s", __FUNCTION__,
|
||||
aBounceTrackingState->Describe().get()));
|
||||
|
||||
// Log a message to the web console for each classified host.
|
||||
nsresult rv = LogBounceTrackersClassifiedToWebConsole(aBounceTrackingState,
|
||||
classifiedHosts);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If running in test automation, dispatch an observer message indicating
|
||||
// we're finished recording bounces.
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_enableTestMode()) {
|
||||
@ -642,9 +524,7 @@ BounceTrackingProtection::TestRunPurgeBounceTrackers(
|
||||
purgedSiteHosts) {
|
||||
promise->MaybeResolve(purgedSiteHosts);
|
||||
},
|
||||
[promise](const PurgeBounceTrackersMozPromise::RejectValueType& error) {
|
||||
promise->MaybeReject(error);
|
||||
});
|
||||
[promise] { promise->MaybeRejectWithUndefined(); });
|
||||
|
||||
promise.forget(aPromise);
|
||||
return NS_OK;
|
||||
@ -705,74 +585,6 @@ BounceTrackingProtection::TestMaybeMigrateUserInteractionPermissions() {
|
||||
return MaybeMigrateUserInteractionPermissions();
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult BounceTrackingProtection::LogBounceTrackersClassifiedToWebConsole(
|
||||
BounceTrackingState* aBounceTrackingState,
|
||||
const nsTArray<nsCString>& aSiteHosts) {
|
||||
NS_ENSURE_ARG(aBounceTrackingState);
|
||||
|
||||
// Nothing to log.
|
||||
if (aSiteHosts.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<dom::BrowsingContext> browsingContext =
|
||||
aBounceTrackingState->CurrentBrowsingContext();
|
||||
if (!browsingContext) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the localized copy from antiTracking.ftl and insert the variables.
|
||||
nsTArray<nsCString> resourceIDs = {"toolkit/global/antiTracking.ftl"_ns};
|
||||
RefPtr<intl::Localization> l10n =
|
||||
intl::Localization::Create(resourceIDs, true);
|
||||
|
||||
for (const nsACString& siteHost : aSiteHosts) {
|
||||
auto l10nArgs = dom::Optional<intl::L10nArgs>();
|
||||
l10nArgs.Construct();
|
||||
|
||||
auto siteHostArg = l10nArgs.Value().Entries().AppendElement();
|
||||
siteHostArg->mKey = "siteHost";
|
||||
siteHostArg->mValue.SetValue().SetAsUTF8String().Assign(siteHost);
|
||||
|
||||
auto gracePeriodArg = l10nArgs.Value().Entries().AppendElement();
|
||||
gracePeriodArg->mKey = "gracePeriodSeconds";
|
||||
gracePeriodArg->mValue.SetValue().SetAsDouble() = StaticPrefs::
|
||||
privacy_bounceTrackingProtection_bounceTrackingGracePeriodSec();
|
||||
|
||||
// Construct the localized string.
|
||||
nsAutoCString message;
|
||||
ErrorResult errorResult;
|
||||
l10n->FormatValueSync("btp-warning-tracker-classified"_ns, l10nArgs,
|
||||
message, errorResult);
|
||||
if (NS_WARN_IF(errorResult.Failed())) {
|
||||
return errorResult.StealNSResult();
|
||||
}
|
||||
|
||||
// Log to the console via nsIScriptError object.
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIScriptError> error =
|
||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = error->InitWithWindowID(
|
||||
NS_ConvertUTF8toUTF16(message), ""_ns, 0, 0,
|
||||
nsIScriptError::warningFlag, "bounceTrackingProtection",
|
||||
browsingContext->GetCurrentInnerWindowId(), true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIConsoleService> consoleService =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The actual log call.
|
||||
rv = consoleService->LogMessage(error);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise>
|
||||
BounceTrackingProtection::EnsureRemoteExceptionListService() {
|
||||
// Check if mRemoteExceptionList is already initialized.
|
||||
@ -799,17 +611,6 @@ BounceTrackingProtection::EnsureRemoteExceptionListService() {
|
||||
|
||||
RefPtr<BounceTrackingProtection::PurgeBounceTrackersMozPromise>
|
||||
BounceTrackingProtection::PurgeBounceTrackers() {
|
||||
// Only purge when the feature is actually enabled.
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_mode() !=
|
||||
nsIBounceTrackingProtection::MODE_ENABLED &&
|
||||
StaticPrefs::privacy_bounceTrackingProtection_mode() !=
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN) {
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug,
|
||||
("%s: Skip: Purging disabled via mode pref.", __FUNCTION__));
|
||||
return PurgeBounceTrackersMozPromise::CreateAndReject(
|
||||
nsresult::NS_ERROR_NOT_AVAILABLE, __func__);
|
||||
}
|
||||
|
||||
// Prevent multiple purge operations from running at the same time.
|
||||
if (mPurgeInProgress) {
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug,
|
||||
@ -943,14 +744,6 @@ nsresult BounceTrackingProtection::PurgeBounceTrackersForStateGlobal(
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug,
|
||||
("%s: %s", __FUNCTION__, aStateGlobal->Describe().get()));
|
||||
|
||||
// Ensure we only purge when pref configuration allows it.
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_mode() !=
|
||||
nsIBounceTrackingProtection::MODE_ENABLED &&
|
||||
StaticPrefs::privacy_bounceTrackingProtection_mode() !=
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
const PRTime now = PR_Now();
|
||||
|
||||
// 1. Remove hosts from the user activation map whose user activation flag has
|
||||
@ -1048,8 +841,7 @@ nsresult BounceTrackingProtection::PurgeBounceTrackersForStateGlobal(
|
||||
__FUNCTION__, PromiseFlatCString(host).get(), bounceTime,
|
||||
aStateGlobal->Describe().get()));
|
||||
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN) {
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_enableDryRunMode()) {
|
||||
// In dry-run mode, we don't actually clear the data, but we still want to
|
||||
// resolve the promise to indicate that the data would have been cleared.
|
||||
cb->OnDataDeleted(0);
|
||||
|
@ -4,7 +4,6 @@
|
||||
#ifndef mozilla_BounceTrackingProtection_h__
|
||||
#define mozilla_BounceTrackingProtection_h__
|
||||
|
||||
#include "BounceTrackingStorageObserver.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "nsIBounceTrackingProtection.h"
|
||||
@ -80,18 +79,6 @@ class BounceTrackingProtection final : public nsIBounceTrackingProtection,
|
||||
// Initializes the singleton instance of BounceTrackingProtection.
|
||||
[[nodiscard]] nsresult Init();
|
||||
|
||||
// Listens for feature pref changes and enables / disables BTP.
|
||||
static void OnPrefChange(const char* aPref, void* aData);
|
||||
|
||||
// Called by OnPrefChange when the mode pref changes.
|
||||
// isStartup indicates whether this is the initial mode change after startup.
|
||||
nsresult OnModeChange(bool aIsStartup);
|
||||
|
||||
// Schedules or cancels the periodic bounce tracker purging. If this method is
|
||||
// called while purging is already scheduled it will cancel the existing timer
|
||||
// and then start a new timer.
|
||||
nsresult UpdateBounceTrackingPurgeTimer(bool aShouldEnable);
|
||||
|
||||
// Keeps track of whether the feature is enabled based on pref state.
|
||||
// Initialized on first call of GetSingleton.
|
||||
static Maybe<bool> sFeatureIsEnabled;
|
||||
@ -99,9 +86,6 @@ class BounceTrackingProtection final : public nsIBounceTrackingProtection,
|
||||
// Timer which periodically runs PurgeBounceTrackers.
|
||||
nsCOMPtr<nsITimer> mBounceTrackingPurgeTimer;
|
||||
|
||||
// Used to notify BounceTrackingState of storage and cookie access.
|
||||
RefPtr<BounceTrackingStorageObserver> mStorageObserver;
|
||||
|
||||
// Storage for user agent globals.
|
||||
RefPtr<BounceTrackingProtectionStorage> mStorage;
|
||||
|
||||
@ -139,13 +123,6 @@ class BounceTrackingProtection final : public nsIBounceTrackingProtection,
|
||||
// is important so we don't purge data for sites the user has interacted with
|
||||
// before the feature was enabled.
|
||||
[[nodiscard]] nsresult MaybeMigrateUserInteractionPermissions();
|
||||
|
||||
// Log a warning about the classification of a site as a bounce tracker. The
|
||||
// message is logged to the devtools console aBounceTrackingState is
|
||||
// associated with.
|
||||
[[nodiscard]] static nsresult LogBounceTrackersClassifiedToWebConsole(
|
||||
BounceTrackingState* aBounceTrackingState,
|
||||
const nsTArray<nsCString>& aSiteHosts);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsIBounceTrackingProtection.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
@ -59,20 +58,6 @@ BounceTrackingProtectionStorage::GetOrCreateStateGlobal(
|
||||
aOriginAttributes);
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtectionStorage::ClearByType(
|
||||
BounceTrackingProtectionStorage::EntryType aType) {
|
||||
for (auto iter = mStateGlobal.Iter(); !iter.Done(); iter.Next()) {
|
||||
BounceTrackingStateGlobal* stateGlobal = iter.Data();
|
||||
MOZ_ASSERT(stateGlobal);
|
||||
// Update in memory state. Skip storage so we can batch the writes later.
|
||||
nsresult rv = stateGlobal->ClearByType(aType, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Clear on-disk state for all OriginAttributes by type.
|
||||
return DeleteDBEntriesByType(nullptr, aType);
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtectionStorage::ClearBySiteHost(
|
||||
const nsACString& aSiteHost, OriginAttributes* aOriginAttributes) {
|
||||
NS_ENSURE_TRUE(!aSiteHost.IsEmpty(), NS_ERROR_INVALID_ARG);
|
||||
@ -277,34 +262,6 @@ nsresult BounceTrackingProtectionStorage::DeleteDBEntriesInTimeRange(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtectionStorage::DeleteDBEntriesByType(
|
||||
OriginAttributes* aOriginAttributes,
|
||||
BounceTrackingProtectionStorage::EntryType aEntryType) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv = WaitForInitialization();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<BounceTrackingProtectionStorage> self = this;
|
||||
Maybe<OriginAttributes> originAttributes;
|
||||
if (aOriginAttributes) {
|
||||
originAttributes.emplace(*aOriginAttributes);
|
||||
}
|
||||
|
||||
IncrementPendingWrites();
|
||||
mBackgroundThread->Dispatch(
|
||||
NS_NewRunnableFunction(
|
||||
"BounceTrackingProtectionStorage::DeleteDBEntriesByType",
|
||||
[self, originAttributes, aEntryType]() {
|
||||
nsresult rv = self->DeleteDataByType(self->mDatabaseConnection,
|
||||
originAttributes, aEntryType);
|
||||
self->DecrementPendingWrites();
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}),
|
||||
NS_DISPATCH_EVENT_MAY_BLOCK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BounceTrackingProtectionStorage::DeleteDBEntriesByOriginAttributesPattern(
|
||||
const OriginAttributesPattern& aOriginAttributesPattern) {
|
||||
@ -457,9 +414,9 @@ nsresult BounceTrackingProtectionStorage::Init() {
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s", __FUNCTION__));
|
||||
|
||||
// Init shouldn't be called if the feature is disabled.
|
||||
NS_ENSURE_TRUE(StaticPrefs::privacy_bounceTrackingProtection_mode() !=
|
||||
nsIBounceTrackingProtection::MODE_DISABLED,
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(
|
||||
StaticPrefs::privacy_bounceTrackingProtection_enabled_AtStartup(),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
// Register a shutdown blocker so we can flush pending changes to disk before
|
||||
// shutdown.
|
||||
@ -827,49 +784,6 @@ nsresult BounceTrackingProtectionStorage::DeleteDataInTimeRange(
|
||||
return deleteStmt->Execute();
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult BounceTrackingProtectionStorage::DeleteDataByType(
|
||||
mozIStorageConnection* aDatabaseConnection,
|
||||
const Maybe<OriginAttributes>& aOriginAttributes,
|
||||
BounceTrackingProtectionStorage::EntryType aEntryType) {
|
||||
MOZ_ASSERT(!NS_IsMainThread(),
|
||||
"Must not write to the table from the main thread.");
|
||||
MOZ_ASSERT(aDatabaseConnection);
|
||||
MOZ_ASSERT(aOriginAttributes.isNothing() ||
|
||||
aOriginAttributes->mPrivateBrowsingId ==
|
||||
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID);
|
||||
|
||||
nsAutoCString deleteQuery(
|
||||
"DELETE FROM sites "
|
||||
"WHERE entryType = :entryType"_ns);
|
||||
|
||||
if (aOriginAttributes) {
|
||||
deleteQuery.AppendLiteral(
|
||||
" AND originAttributeSuffix = :originAttributeSuffix");
|
||||
}
|
||||
|
||||
deleteQuery.AppendLiteral(";");
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> deleteStmt;
|
||||
nsresult rv = aDatabaseConnection->CreateStatement(
|
||||
deleteQuery, getter_AddRefs(deleteStmt));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = deleteStmt->BindInt32ByName("entryType"_ns,
|
||||
static_cast<int32_t>(aEntryType));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aOriginAttributes) {
|
||||
nsAutoCString originAttributeSuffix;
|
||||
aOriginAttributes->CreateSuffix(originAttributeSuffix);
|
||||
rv = deleteStmt->BindUTF8StringByName("originAttributeSuffix"_ns,
|
||||
originAttributeSuffix);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return deleteStmt->Execute();
|
||||
}
|
||||
|
||||
nsresult BounceTrackingProtectionStorage::DeleteDataByOriginAttributesPattern(
|
||||
mozIStorageConnection* aDatabaseConnection,
|
||||
const OriginAttributesPattern& aOriginAttributesPattern) {
|
||||
|
@ -64,10 +64,6 @@ class BounceTrackingProtectionStorage final : public nsIObserver,
|
||||
// migration.
|
||||
enum class EntryType : uint8_t { BounceTracker = 0, UserActivation = 1 };
|
||||
|
||||
// Clear all user activation or bounce tracker entries.
|
||||
[[nodiscard]] nsresult ClearByType(
|
||||
BounceTrackingProtectionStorage::EntryType aType);
|
||||
|
||||
// Clear all state for a given site host. If aOriginAttributes is passed, only
|
||||
// entries for that OA will be deleted.
|
||||
[[nodiscard]] nsresult ClearBySiteHost(const nsACString& aSiteHost,
|
||||
@ -149,13 +145,6 @@ class BounceTrackingProtectionStorage final : public nsIObserver,
|
||||
Maybe<PRTime> aTo,
|
||||
Maybe<BounceTrackingProtectionStorage::EntryType> aEntryType = Nothing{});
|
||||
|
||||
// Delete all entries of a specific type.
|
||||
// aOriginAttributes can be passed
|
||||
[[nodiscard]] nsresult DeleteDataByType(
|
||||
mozIStorageConnection* aDatabaseConnection,
|
||||
const Maybe<OriginAttributes>& aOriginAttributes,
|
||||
BounceTrackingProtectionStorage::EntryType aEntryType);
|
||||
|
||||
// Delete all entries matching the given OriginAttributesPattern. Worker
|
||||
// thread only.
|
||||
[[nodiscard]] static nsresult DeleteDataByOriginAttributesPattern(
|
||||
@ -206,12 +195,6 @@ class BounceTrackingProtectionStorage final : public nsIObserver,
|
||||
OriginAttributes* aOriginAttributes, PRTime aFrom,
|
||||
Maybe<PRTime> aTo = Nothing{}, Maybe<EntryType> aEntryType = Nothing{});
|
||||
|
||||
// Delete all DB entries matching the given type.
|
||||
// If aOriginAttributes is passed it acts as an additional filter.
|
||||
[[nodiscard]] nsresult DeleteDBEntriesByType(
|
||||
OriginAttributes* aOriginAttributes,
|
||||
BounceTrackingProtectionStorage::EntryType aEntryType);
|
||||
|
||||
// Deletes all DB entries matching the given OriginAttributesPattern.
|
||||
[[nodiscard]] nsresult DeleteDBEntriesByOriginAttributesPattern(
|
||||
const OriginAttributesPattern& aOriginAttributesPattern);
|
||||
|
@ -39,21 +39,17 @@ namespace mozilla {
|
||||
static StaticAutoPtr<nsTHashMap<uint64_t, WeakPtr<BounceTrackingState>>>
|
||||
sBounceTrackingStates;
|
||||
|
||||
static StaticRefPtr<BounceTrackingStorageObserver> sStorageObserver;
|
||||
|
||||
NS_IMPL_ISUPPORTS(BounceTrackingState, nsIWebProgressListener,
|
||||
nsISupportsWeakReference);
|
||||
|
||||
BounceTrackingState::BounceTrackingState() {
|
||||
MOZ_ASSERT(StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED ||
|
||||
StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN);
|
||||
MOZ_ASSERT(StaticPrefs::privacy_bounceTrackingProtection_enabled_AtStartup());
|
||||
mBounceTrackingProtection = BounceTrackingProtection::GetSingleton();
|
||||
};
|
||||
|
||||
BounceTrackingState::~BounceTrackingState() {
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Verbose,
|
||||
("BounceTrackingState destructor"));
|
||||
|
||||
if (sBounceTrackingStates) {
|
||||
sBounceTrackingStates->Remove(mBrowserId);
|
||||
}
|
||||
@ -112,55 +108,21 @@ already_AddRefed<BounceTrackingState> BounceTrackingState::GetOrCreate(
|
||||
}
|
||||
sBounceTrackingStates->InsertOrUpdate(browserId, newBTS);
|
||||
|
||||
// And the storage observer.
|
||||
if (!sStorageObserver) {
|
||||
sStorageObserver = new BounceTrackingStorageObserver();
|
||||
ClearOnShutdown(&sStorageObserver);
|
||||
|
||||
aRv = sStorageObserver->Init();
|
||||
NS_ENSURE_SUCCESS(aRv, nullptr);
|
||||
}
|
||||
|
||||
return newBTS.forget();
|
||||
};
|
||||
|
||||
// static
|
||||
void BounceTrackingState::ResetAll() { Reset(nullptr, nullptr); }
|
||||
|
||||
// static
|
||||
void BounceTrackingState::DestroyAll() {
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s", __FUNCTION__));
|
||||
if (!sBounceTrackingStates) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fully reset all BounceTrackingStates, so even if some don't get destroyed
|
||||
// straight away things like running timers are stopped.
|
||||
BounceTrackingState::Reset(nullptr, nullptr);
|
||||
|
||||
// Destroy all BounceTrackingState objects.
|
||||
for (auto iter = sBounceTrackingStates->Iter(); !iter.Done(); iter.Next()) {
|
||||
WeakPtr<BounceTrackingState> bts = iter.Data();
|
||||
// Need to remove the element from the map prior to calling Destroy()
|
||||
// because the destructor also updates the map and we can't iterate and
|
||||
// externally modify the map at the same time. This way the Remove() call of
|
||||
// the destructor is a no-op.
|
||||
iter.Remove();
|
||||
if (!bts) {
|
||||
continue;
|
||||
}
|
||||
// Destroy the BounceTrackingState by dropping references to it. This is
|
||||
// best effort. If something still holds a reference it still stay alive
|
||||
// longer.
|
||||
// Tell the web progress to drop the BTS reference.
|
||||
RefPtr<dom::BrowsingContext> browsingContext =
|
||||
bts->CurrentBrowsingContext();
|
||||
if (!browsingContext) {
|
||||
continue;
|
||||
}
|
||||
dom::BrowsingContextWebProgress* webProgress =
|
||||
browsingContext->Canonical()->GetWebProgress();
|
||||
if (!webProgress) {
|
||||
continue;
|
||||
}
|
||||
webProgress->DropBounceTrackingState();
|
||||
}
|
||||
|
||||
// Clean up the map.
|
||||
sBounceTrackingStates = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void BounceTrackingState::ResetAllForOriginAttributes(
|
||||
const OriginAttributes& aOriginAttributes) {
|
||||
@ -175,19 +137,14 @@ void BounceTrackingState::ResetAllForOriginAttributesPattern(
|
||||
|
||||
nsresult BounceTrackingState::Init(
|
||||
dom::BrowsingContextWebProgress* aWebProgress) {
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug,
|
||||
("BounceTrackingState::%s", __FUNCTION__));
|
||||
|
||||
MOZ_ASSERT(!mIsInitialized,
|
||||
"BounceTrackingState must not be initialized twice.");
|
||||
mIsInitialized = true;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aWebProgress);
|
||||
NS_ENSURE_TRUE(StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED ||
|
||||
StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(
|
||||
StaticPrefs::privacy_bounceTrackingProtection_enabled_AtStartup(),
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mBounceTrackingProtection, NS_ERROR_FAILURE);
|
||||
|
||||
// Store the browser ID so we can get the associated BC later without having
|
||||
@ -203,8 +160,11 @@ nsresult BounceTrackingState::Init(
|
||||
|
||||
// Add a listener for window load. See BounceTrackingState::OnStateChange for
|
||||
// the listener code.
|
||||
return aWebProgress->AddProgressListener(this,
|
||||
nsIWebProgress::NOTIFY_STATE_WINDOW);
|
||||
nsresult rv = aWebProgress->AddProgressListener(
|
||||
this, nsIWebProgress::NOTIFY_STATE_WINDOW);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void BounceTrackingState::ResetBounceTrackingRecord() {
|
||||
@ -266,10 +226,8 @@ bool BounceTrackingState::ShouldCreateBounceTrackingStateForWebProgress(
|
||||
dom::BrowsingContextWebProgress* aWebProgress) {
|
||||
NS_ENSURE_TRUE(aWebProgress, false);
|
||||
|
||||
uint8_t mode = StaticPrefs::privacy_bounceTrackingProtection_mode();
|
||||
// Classification / purging is disabled.
|
||||
if (mode != nsIBounceTrackingProtection::MODE_ENABLED &&
|
||||
mode != nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN) {
|
||||
// Feature is globally disabled.
|
||||
if (!StaticPrefs::privacy_bounceTrackingProtection_enabled_AtStartup()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -49,15 +49,8 @@ class BounceTrackingState : public nsIWebProgressListener,
|
||||
// Reset state for all BounceTrackingState instances this includes resetting
|
||||
// BounceTrackingRecords and cancelling any running timers.
|
||||
static void ResetAll();
|
||||
|
||||
// Resets and destroys all BounceTrackingState objects. This is used when the
|
||||
// feature gets disabled.
|
||||
static void DestroyAll();
|
||||
|
||||
// Reset BounceTrackingState objects matching OriginAttributes.
|
||||
static void ResetAllForOriginAttributes(
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
// Same as above but for a pattern.
|
||||
static void ResetAllForOriginAttributesPattern(
|
||||
const OriginAttributesPattern& aPattern);
|
||||
|
||||
|
@ -206,26 +206,6 @@ nsresult BounceTrackingStateGlobal::RemoveBounceTrackers(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BounceTrackingStateGlobal::ClearByType(
|
||||
BounceTrackingProtectionStorage::EntryType aType, bool aSkipStorage) {
|
||||
if (aType == BounceTrackingProtectionStorage::EntryType::BounceTracker) {
|
||||
mBounceTrackers.Clear();
|
||||
} else {
|
||||
MOZ_ASSERT(aType ==
|
||||
BounceTrackingProtectionStorage::EntryType::UserActivation);
|
||||
mUserActivation.Clear();
|
||||
}
|
||||
|
||||
if (aSkipStorage || !ShouldPersistToDisk()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(mStorage, NS_ERROR_FAILURE);
|
||||
return mStorage->DeleteDBEntriesByType(
|
||||
&mOriginAttributes,
|
||||
BounceTrackingProtectionStorage::EntryType::BounceTracker);
|
||||
}
|
||||
|
||||
// static
|
||||
nsCString BounceTrackingStateGlobal::DescribeMap(
|
||||
const nsTHashMap<nsCStringHashKey, PRTime>& aMap) {
|
||||
|
@ -66,10 +66,6 @@ class BounceTrackingStateGlobal final {
|
||||
[[nodiscard]] nsresult RemoveBounceTrackers(
|
||||
const nsTArray<nsCString>& aSiteHosts);
|
||||
|
||||
// Clear user activation or bounce tracker map.
|
||||
[[nodiscard]] nsresult ClearByType(
|
||||
BounceTrackingProtectionStorage::EntryType aType, bool aSkipStorage);
|
||||
|
||||
[[nodiscard]] nsresult ClearSiteHost(const nsACString& aSiteHost,
|
||||
bool aSkipStorage = false);
|
||||
|
||||
|
@ -18,25 +18,21 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(BounceTrackingStorageObserver, nsIObserver,
|
||||
nsISupportsWeakReference);
|
||||
NS_IMPL_ISUPPORTS(BounceTrackingStorageObserver, nsIObserver);
|
||||
|
||||
nsresult BounceTrackingStorageObserver::Init() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug,
|
||||
("BounceTrackingStorageObserver::%s", __FUNCTION__));
|
||||
MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s", __FUNCTION__));
|
||||
|
||||
// Add observers to listen for cookie changes.
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(observerService, NS_ERROR_FAILURE);
|
||||
|
||||
// Passing ownsWeak=true so we don't have to unregister the observer when
|
||||
// BounceTrackingStorageObserver gets destroyed.
|
||||
nsresult rv = observerService->AddObserver(this, "cookie-changed", true);
|
||||
nsresult rv = observerService->AddObserver(this, "cookie-changed", false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return observerService->AddObserver(this, "private-cookie-changed", true);
|
||||
return observerService->AddObserver(this, "private-cookie-changed", false);
|
||||
}
|
||||
|
||||
// nsIObserver
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -16,19 +15,19 @@ class WindowContext;
|
||||
|
||||
extern LazyLogModule gBounceTrackingProtectionLog;
|
||||
|
||||
class BounceTrackingStorageObserver : public nsIObserver,
|
||||
public nsSupportsWeakReference {
|
||||
class BounceTrackingStorageObserver final : public nsIObserver {
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
public:
|
||||
BounceTrackingStorageObserver() = default;
|
||||
[[nodiscard]] nsresult Init();
|
||||
|
||||
[[nodiscard]] static nsresult OnInitialStorageAccess(
|
||||
dom::WindowContext* aWindowContext);
|
||||
|
||||
[[nodiscard]] nsresult Init();
|
||||
|
||||
private:
|
||||
virtual ~BounceTrackingStorageObserver() = default;
|
||||
~BounceTrackingStorageObserver() = default;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "ClearDataCallback.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "nsIBounceTrackingProtection.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "nsNetCID.h"
|
||||
@ -46,8 +45,7 @@ ClearDataCallback::ClearDataCallback(ClearDataMozPromise::Private* aPromise,
|
||||
mClearDurationTimer(0) {
|
||||
MOZ_ASSERT(!aHost.IsEmpty(), "Host must not be empty");
|
||||
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED) {
|
||||
if (!StaticPrefs::privacy_bounceTrackingProtection_enableDryRunMode()) {
|
||||
// Only collect timing information when actually performing the deletion
|
||||
mClearDurationTimer =
|
||||
glean::bounce_tracking_protection::purge_duration.Start();
|
||||
@ -114,8 +112,7 @@ void ClearDataCallback::RecordClearDurationTelemetry() {
|
||||
}
|
||||
|
||||
void ClearDataCallback::RecordPurgeCountTelemetry(bool aFailed) {
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN) {
|
||||
if (StaticPrefs::privacy_bounceTrackingProtection_enableDryRunMode()) {
|
||||
MOZ_ASSERT(aFailed == 0, "Dry-run purge can't fail");
|
||||
glean::bounce_tracking_protection::purge_count.Get("dry"_ns).Add(1);
|
||||
} else if (aFailed) {
|
||||
@ -183,8 +180,8 @@ void ClearDataCallback::RecordPurgeEventTelemetry(bool aSuccess) {
|
||||
// Record a glean event for the clear action.
|
||||
glean::bounce_tracking_protection::PurgeActionExtra extra = {
|
||||
.bounceTime = Some(mBounceTime / PR_USEC_PER_SEC),
|
||||
.isDryRun = Some(StaticPrefs::privacy_bounceTrackingProtection_mode() ==
|
||||
nsIBounceTrackingProtection::MODE_ENABLED_DRY_RUN),
|
||||
.isDryRun = Some(
|
||||
StaticPrefs::privacy_bounceTrackingProtection_enableDryRunMode()),
|
||||
.siteHost = Some(mHost),
|
||||
.success = Some(aSuccess),
|
||||
};
|
||||
|
@ -7,37 +7,6 @@
|
||||
|
||||
[scriptable, uuid(4866F748-29DA-4C10-8EAA-ED2F7851E6B1)]
|
||||
interface nsIBounceTrackingProtection : nsISupports {
|
||||
/**
|
||||
* Modes for Bounce Tracking Protection
|
||||
*
|
||||
* MODE_DISABLED - Feature fully disabled and not initialized at startup. No
|
||||
* user activation signals are collected. Requires a restart to apply.
|
||||
* MODE_ENABLED - Feature fully enabled. This includes: collection of user
|
||||
* activation signals, classification of bounce trackers, periodic purging
|
||||
* of bounce trackers.
|
||||
* MODE_ENABLED_STANDBY - Tracker classification and purging is disabled.
|
||||
* User activation signals are still collected and stored.
|
||||
* MODE_ENABLED_DRY_RUN - Dry-run mode: The feature is fully enabled, but
|
||||
* tracker purging is simulated. No site data is purged. Purge telemetry
|
||||
* still gets collected. This mode is helpful for testing the feature
|
||||
* without risking data loss.
|
||||
*
|
||||
* For toggling the feature in privacy settings UI switch between
|
||||
* MODE_ENABLED and MODE_NO_PURGE. This is important so that user activation
|
||||
* signals are still collected even if the feature is "turned off" for the
|
||||
* user.
|
||||
* Fully enabling / disabling the feature (MODE_DISABLED -> x or x ->
|
||||
* MODE_DISABLED) requires a restart to apply.
|
||||
*/
|
||||
cenum Modes : 8 {
|
||||
MODE_DISABLED = 0,
|
||||
MODE_ENABLED = 1,
|
||||
MODE_ENABLED_STANDBY = 2,
|
||||
MODE_ENABLED_DRY_RUN = 3,
|
||||
// Not a valid mode, only used for pref validation.
|
||||
MAX_MODE_VALUE = 3,
|
||||
};
|
||||
|
||||
// Reset the global bounce tracking state, including the maps for tracking
|
||||
// bounce tracker candidates and user activation.
|
||||
void clearAll();
|
||||
|
@ -1,9 +1,10 @@
|
||||
[DEFAULT]
|
||||
head = "head.js"
|
||||
prefs = [
|
||||
"privacy.bounceTrackingProtection.mode=1",
|
||||
"privacy.bounceTrackingProtection.enabled=true",
|
||||
"privacy.bounceTrackingProtection.enableTestMode=true",
|
||||
"privacy.bounceTrackingProtection.bounceTrackingPurgeTimerPeriodSec=0",
|
||||
"privacy.bounceTrackingProtection.enableDryRunMode=false",
|
||||
# Do not upgrade ORIGIN_TRACKER_B, all other origins are already HTTPS
|
||||
"dom.security.https_first=false",
|
||||
]
|
||||
@ -16,11 +17,9 @@ support-files = [
|
||||
"file_web_worker.js",
|
||||
]
|
||||
|
||||
["browser_bouncetracking_cookie_behavior.js"]
|
||||
|
||||
["browser_bouncetracking_dry_run.js"]
|
||||
|
||||
["browser_bouncetracking_mode_prefs.js"]
|
||||
["browser_bouncetracking_initialize.js"]
|
||||
|
||||
["browser_bouncetracking_oa_isolation.js"]
|
||||
|
||||
@ -52,5 +51,3 @@ support-files = [
|
||||
|
||||
["browser_bouncetracking_webAuthUserActivation.js"]
|
||||
support-files = ["!/dom/webauthn/tests/browser/head.js"]
|
||||
|
||||
["browser_bouncetracking_web_console.js"]
|
||||
|
@ -1,103 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// The test needs to open new PBM windows which is slow on debug builds.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
/**
|
||||
* Helper function for testing that BTP gets enabled/disabled for a specific
|
||||
* cookie behavior.
|
||||
*
|
||||
* @param {Number} cookieBehavior - One of Ci.nsICookieService.BEHAVIOR* values.
|
||||
* @param {Number} privateBrowsingId - Run test in private/non-private mode.
|
||||
*/
|
||||
async function runTestCookieBehavior(
|
||||
cookieBehavior,
|
||||
privateBrowsingId,
|
||||
shouldBeEnabled
|
||||
) {
|
||||
info(
|
||||
"runTestCookieBehavior " +
|
||||
JSON.stringify({ cookieBehavior, privateBrowsingId, shouldBeEnabled })
|
||||
);
|
||||
if (privateBrowsingId == 0) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior", cookieBehavior]],
|
||||
});
|
||||
} else {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior.pbmode", cookieBehavior]],
|
||||
});
|
||||
}
|
||||
|
||||
await runTestBounce({
|
||||
bounceType: "server",
|
||||
setState: "cookie-server",
|
||||
originAttributes: {
|
||||
privateBrowsingId,
|
||||
},
|
||||
expectRecordBounces: shouldBeEnabled,
|
||||
expectCandidate: shouldBeEnabled,
|
||||
expectPurge: shouldBeEnabled,
|
||||
});
|
||||
|
||||
// Cleanup
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["privacy.bounceTrackingProtection.requireStatefulBounces", true],
|
||||
["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests classification + purging with different cookie behavior settings.
|
||||
*/
|
||||
add_task(async function test_cookie_behaviors() {
|
||||
for (let pbId = 0; pbId < 2; pbId++) {
|
||||
// BTP is disabled
|
||||
await runTestCookieBehavior(
|
||||
Ci.nsICookieService.BEHAVIOR_ACCEPT,
|
||||
pbId,
|
||||
false
|
||||
);
|
||||
await runTestCookieBehavior(
|
||||
Ci.nsICookieService.BEHAVIOR_REJECT,
|
||||
pbId,
|
||||
false
|
||||
);
|
||||
|
||||
// BTP is enabled
|
||||
await runTestCookieBehavior(
|
||||
Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN,
|
||||
pbId,
|
||||
true
|
||||
);
|
||||
await runTestCookieBehavior(
|
||||
Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN,
|
||||
pbId,
|
||||
true
|
||||
);
|
||||
await runTestCookieBehavior(
|
||||
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
|
||||
pbId,
|
||||
true
|
||||
);
|
||||
await runTestCookieBehavior(
|
||||
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
|
||||
pbId,
|
||||
true
|
||||
);
|
||||
}
|
||||
Assert.equal(
|
||||
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
|
||||
Ci.nsICookieService.BEHAVIOR_LAST,
|
||||
"test covers all cookie behaviors"
|
||||
);
|
||||
});
|
@ -86,12 +86,7 @@ add_setup(async function () {
|
||||
|
||||
add_task(async function test_purge_in_regular_mode() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"privacy.bounceTrackingProtection.mode",
|
||||
Ci.nsIBounceTrackingProtection.MODE_ENABLED,
|
||||
],
|
||||
],
|
||||
set: [["privacy.bounceTrackingProtection.enableDryRunMode", false]],
|
||||
});
|
||||
|
||||
await runPurgeTest(true);
|
||||
@ -99,12 +94,7 @@ add_task(async function test_purge_in_regular_mode() {
|
||||
|
||||
add_task(async function test_purge_in_dry_run_mode() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"privacy.bounceTrackingProtection.mode",
|
||||
Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN,
|
||||
],
|
||||
],
|
||||
set: [["privacy.bounceTrackingProtection.enableDryRunMode", true]],
|
||||
});
|
||||
|
||||
await runPurgeTest(false);
|
||||
|
@ -0,0 +1,68 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* helper function for testing that btp was initialized
|
||||
*
|
||||
* @param {Number} cookieMode: one of Ci.nsICookieService.BEHAVIOR* values
|
||||
* @param {Number} privateBrowsingId: run test in private/non-private mode
|
||||
*/
|
||||
async function testInit(cookieMode, privateBrowsingId) {
|
||||
if (privateBrowsingId != 0) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior", cookieMode]],
|
||||
});
|
||||
} else {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior.pbmode", cookieMode]],
|
||||
});
|
||||
}
|
||||
|
||||
let originAttributes = {
|
||||
privateBrowsingId,
|
||||
};
|
||||
|
||||
info("Run server bounce with cookie.");
|
||||
await runTestBounce({
|
||||
bounceType: "server",
|
||||
setState: "cookie-server",
|
||||
originAttributes,
|
||||
postBounceCallback: () => {
|
||||
// Make sure we recorded bounceTracking
|
||||
let numTrackersPurged =
|
||||
bounceTrackingProtection.testGetBounceTrackerCandidateHosts(
|
||||
originAttributes
|
||||
).length;
|
||||
Assert.equal(numTrackersPurged, 1, "All tracker candidates found.");
|
||||
},
|
||||
});
|
||||
|
||||
// Cleanup
|
||||
await SpecialPowers.popPrefEnv();
|
||||
Services.fog.testResetFOG();
|
||||
bounceTrackingProtection.clearAll();
|
||||
}
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["privacy.bounceTrackingProtection.requireStatefulBounces", true],
|
||||
["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function () {
|
||||
for (let pbId = 0; pbId < 2; pbId++) {
|
||||
await testInit(Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN, pbId);
|
||||
await testInit(Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN, pbId);
|
||||
await testInit(Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER, pbId);
|
||||
}
|
||||
Assert.equal(
|
||||
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
|
||||
Ci.nsICookieService.BEHAVIOR_LAST,
|
||||
"test covers all cookie behaviours"
|
||||
);
|
||||
});
|
@ -1,139 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
MODE_DISABLED,
|
||||
MODE_ENABLED,
|
||||
MODE_ENABLED_STANDBY,
|
||||
MODE_ENABLED_DRY_RUN,
|
||||
} = Ci.nsIBounceTrackingProtection;
|
||||
|
||||
const BTP_MODE_PREF = "privacy.bounceTrackingProtection.mode";
|
||||
|
||||
/**
|
||||
* Run a bounce test with a custom bounce tracking protection mode.
|
||||
* @param {Number} mode - Mode to set for BTP. Any of
|
||||
* Ci.nsIBounceTrackingProtection.MODE_*
|
||||
* @param {boolean} shouldBeEnabled - Whether BTP should classify + purge in
|
||||
* this mode.
|
||||
*/
|
||||
async function runTestModePref(mode, shouldBeEnabled) {
|
||||
info("runTestModePref " + JSON.stringify({ mode, shouldBeEnabled }));
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[BTP_MODE_PREF, mode]],
|
||||
});
|
||||
|
||||
info("Run server bounce with cookie.");
|
||||
await runTestBounce({
|
||||
bounceType: "server",
|
||||
setState: "cookie-server",
|
||||
expectRecordBounces: shouldBeEnabled,
|
||||
expectCandidate: shouldBeEnabled,
|
||||
expectPurge: shouldBeEnabled,
|
||||
});
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["privacy.bounceTrackingProtection.requireStatefulBounces", true],
|
||||
["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests classification + purging with different BTP modes.
|
||||
*/
|
||||
add_task(async function test_mode_pref() {
|
||||
await runTestModePref(MODE_DISABLED, false);
|
||||
await runTestModePref(MODE_ENABLED, true);
|
||||
await runTestModePref(MODE_ENABLED_STANDBY, false);
|
||||
await runTestModePref(MODE_ENABLED_DRY_RUN, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that when the BTP mode is switched the bounce tracker candidate list is
|
||||
* cleared.
|
||||
*/
|
||||
add_task(async function test_mode_switch_clears_bounce_candidates() {
|
||||
// Start with MODE_ENABLED
|
||||
let modeOriginal = Services.prefs.getIntPref(BTP_MODE_PREF);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.setIntPref(BTP_MODE_PREF, modeOriginal);
|
||||
bounceTrackingProtection.clearAll();
|
||||
});
|
||||
|
||||
info(
|
||||
"Populate BTP state: Add bounce tracker candidates and a user activation."
|
||||
);
|
||||
bounceTrackingProtection.testAddBounceTrackerCandidate(
|
||||
{},
|
||||
"bounce-tracker.com",
|
||||
1
|
||||
);
|
||||
bounceTrackingProtection.testAddBounceTrackerCandidate(
|
||||
{},
|
||||
"another-bounce-tracker.net",
|
||||
2
|
||||
);
|
||||
bounceTrackingProtection.testAddUserActivation(
|
||||
{},
|
||||
"user-activation.com",
|
||||
400
|
||||
);
|
||||
Assert.equal(
|
||||
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
|
||||
2,
|
||||
"Bounce tracker candidate map should have been populated."
|
||||
);
|
||||
Assert.equal(
|
||||
bounceTrackingProtection.testGetUserActivationHosts({}).length,
|
||||
1,
|
||||
"User activation map should have been populated."
|
||||
);
|
||||
|
||||
info("Update to MODE_ENABLED_DRY_RUN");
|
||||
Services.prefs.setIntPref(BTP_MODE_PREF, MODE_ENABLED_DRY_RUN);
|
||||
|
||||
Assert.equal(
|
||||
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
|
||||
0,
|
||||
"Mode change should have cleared bouncer tracker candidate map."
|
||||
);
|
||||
Assert.equal(
|
||||
bounceTrackingProtection.testGetUserActivationHosts({}).length,
|
||||
1,
|
||||
"Mode change should NOT have cleared user activation map."
|
||||
);
|
||||
|
||||
info("Add a new bounce tracker");
|
||||
bounceTrackingProtection.testAddBounceTrackerCandidate(
|
||||
{},
|
||||
"bounce-tracker2.com",
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
|
||||
1,
|
||||
"Bounce tracker candidate map should have been populated."
|
||||
);
|
||||
|
||||
info("Switch back to MODE_ENABLED");
|
||||
Services.prefs.setIntPref(BTP_MODE_PREF, MODE_ENABLED);
|
||||
|
||||
Assert.equal(
|
||||
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
|
||||
0,
|
||||
"Mode change should have cleared bouncer tracker candidate map."
|
||||
);
|
||||
Assert.equal(
|
||||
bounceTrackingProtection.testGetUserActivationHosts({}).length,
|
||||
1,
|
||||
"Mode change should NOT have cleared user activation map."
|
||||
);
|
||||
});
|
@ -23,14 +23,7 @@ function assertCounterNull() {
|
||||
|
||||
async function testPurgeCount(isDryRunMode) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"privacy.bounceTrackingProtection.mode",
|
||||
isDryRunMode
|
||||
? Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN
|
||||
: Ci.nsIBounceTrackingProtection.MODE_ENABLED,
|
||||
],
|
||||
],
|
||||
set: [["privacy.bounceTrackingProtection.enableDryRunMode", isDryRunMode]],
|
||||
});
|
||||
|
||||
assertCounterNull();
|
||||
|
@ -7,14 +7,7 @@ let bounceTrackingProtection;
|
||||
|
||||
async function test_purge_duration(isDryRunMode) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"privacy.bounceTrackingProtection.mode",
|
||||
isDryRunMode
|
||||
? Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN
|
||||
: Ci.nsIBounceTrackingProtection.MODE_ENABLED,
|
||||
],
|
||||
],
|
||||
set: [["privacy.bounceTrackingProtection.enableDryRunMode", isDryRunMode]],
|
||||
});
|
||||
|
||||
is(
|
||||
|
@ -22,14 +22,7 @@ add_setup(async function () {
|
||||
|
||||
async function runTest(useDryRunMode) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"privacy.bounceTrackingProtection.mode",
|
||||
useDryRunMode
|
||||
? Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN
|
||||
: Ci.nsIBounceTrackingProtection.MODE_ENABLED,
|
||||
],
|
||||
],
|
||||
set: [["privacy.bounceTrackingProtection.enableDryRunMode", useDryRunMode]],
|
||||
});
|
||||
|
||||
is(
|
||||
|
@ -1,73 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let btpGracePeriodSec = Services.prefs.getIntPref(
|
||||
"privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec"
|
||||
);
|
||||
|
||||
/**
|
||||
* Registers a console listener and waits for the bounce tracker classified message
|
||||
* to be logged.
|
||||
* @returns {Promise} - Promise which resolves once the message has been logged.
|
||||
*/
|
||||
async function waitForBounceTrackerClassifiedMessage(siteHost) {
|
||||
let lastMessage;
|
||||
// Checking if the grace period is
|
||||
// privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec requires
|
||||
// extra steps because l10n applies further transformations to the number such
|
||||
// as adding a ",".
|
||||
let gracePeriodFormatted = new Intl.NumberFormat("en-US", {
|
||||
useGrouping: true,
|
||||
}).format(
|
||||
Services.prefs.getIntPref(
|
||||
"privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec"
|
||||
)
|
||||
);
|
||||
let isBTPClassifiedMsg = msg =>
|
||||
msg.includes(
|
||||
`“${siteHost}” has been classified as a bounce tracker. If it does not receive user activation within the next ${gracePeriodFormatted} seconds it will have its state purged.`
|
||||
);
|
||||
await new Promise(resolve => {
|
||||
SpecialPowers.registerConsoleListener(consoleMsg => {
|
||||
if (!consoleMsg?.message || consoleMsg.message == "SENTINEL") {
|
||||
return;
|
||||
}
|
||||
lastMessage = consoleMsg;
|
||||
if (isBTPClassifiedMsg(consoleMsg.message)) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
SpecialPowers.postConsoleSentinel();
|
||||
|
||||
ok(lastMessage.isScriptError, "Message should be script error.");
|
||||
ok(lastMessage.isWarning, "Message should be a warning.");
|
||||
|
||||
ok(
|
||||
isBTPClassifiedMsg(lastMessage.message),
|
||||
"Observed bounce tracker classified console message."
|
||||
);
|
||||
}
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["privacy.bounceTrackingProtection.requireStatefulBounces", true],
|
||||
["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_bounce_tracker_classified_web_console_message() {
|
||||
let consoleMsgPromise = waitForBounceTrackerClassifiedMessage(SITE_TRACKER);
|
||||
|
||||
info("Run server bounce with cookie.");
|
||||
await runTestBounce({
|
||||
bounceType: "server",
|
||||
setState: "cookie-server",
|
||||
});
|
||||
|
||||
await consoleMsgPromise;
|
||||
});
|
@ -231,21 +231,15 @@ async function navigateLinkClick(
|
||||
* run for the given browser.
|
||||
*/
|
||||
async function waitForRecordBounces(browser) {
|
||||
let { browserId } = browser.browsingContext;
|
||||
info(
|
||||
`waitForRecordBounces: Waiting for record bounces for browser: ${browserId}.`
|
||||
);
|
||||
|
||||
await TestUtils.topicObserved(
|
||||
return TestUtils.topicObserved(
|
||||
OBSERVER_MSG_RECORD_BOUNCES_FINISHED,
|
||||
subject => {
|
||||
// Ensure the message was dispatched for the browser we're interested in.
|
||||
let propBag = subject.QueryInterface(Ci.nsIPropertyBag2);
|
||||
return browserId == propBag.getProperty("browserId");
|
||||
let browserId = propBag.getProperty("browserId");
|
||||
return browser.browsingContext.browserId == browserId;
|
||||
}
|
||||
);
|
||||
|
||||
info(`waitForRecordBounces: Recorded bounces for browser ${browserId}.`);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -269,9 +263,6 @@ async function waitForRecordBounces(browser) {
|
||||
* @param {('same-site'|'cross-site')} [options.setCookieViaImage] - Whether to
|
||||
* set the state via an image request. Only applies to setState ==
|
||||
* "cookie-server".
|
||||
* @param {boolean} [options.expectRecordBounces=true] - Whether the record
|
||||
* bounces algorithm runs and we should wait for the test message. This
|
||||
* shouldn't run when the feature is disabled.
|
||||
* @param {boolean} [options.expectCandidate=true] - Expect the redirecting site
|
||||
* to be identified as a bounce tracker (candidate).
|
||||
* @param {boolean} [options.expectPurge=true] - Expect the redirecting site to
|
||||
@ -295,7 +286,6 @@ async function runTestBounce(options = {}) {
|
||||
setStateInWebWorker = false,
|
||||
setStateInNestedWebWorker = false,
|
||||
setCookieViaImage = null,
|
||||
expectRecordBounces = true,
|
||||
expectCandidate = true,
|
||||
expectPurge = true,
|
||||
originAttributes = {},
|
||||
@ -342,10 +332,7 @@ async function runTestBounce(options = {}) {
|
||||
let browser = tab.linkedBrowser;
|
||||
await BrowserTestUtils.browserLoaded(browser, true, initialURL);
|
||||
|
||||
let promiseRecordBounces;
|
||||
if (expectRecordBounces) {
|
||||
promiseRecordBounces = waitForRecordBounces(browser);
|
||||
}
|
||||
let promiseRecordBounces = waitForRecordBounces(browser);
|
||||
|
||||
// The final destination after the bounce.
|
||||
let targetURL = new URL(getBaseUrl(ORIGIN_B) + "file_start.html");
|
||||
@ -376,26 +363,14 @@ async function runTestBounce(options = {}) {
|
||||
|
||||
// Navigate again with user gesture which triggers
|
||||
// BounceTrackingProtection::RecordStatefulBounces. We could rely on the
|
||||
// timeout (mClientBounceDetectionTimeout) here but that can cause races in
|
||||
// debug where the load is quite slow.
|
||||
let finalTargetURL = new URL(getBaseUrl(ORIGIN_C) + "file_start.html");
|
||||
let finalLoadPromise = BrowserTestUtils.browserLoaded(
|
||||
// timeout (mClientBounceDetectionTimeout) here but that can cause races
|
||||
// in debug where the load is quite slow.
|
||||
await navigateLinkClick(
|
||||
browser,
|
||||
true,
|
||||
initialURL.href
|
||||
new URL(getBaseUrl(ORIGIN_C) + "file_start.html")
|
||||
);
|
||||
await navigateLinkClick(browser, finalTargetURL);
|
||||
await finalLoadPromise;
|
||||
|
||||
if (expectRecordBounces) {
|
||||
await promiseRecordBounces;
|
||||
} else {
|
||||
// If we don't expect classification to happen only wait for navigation from
|
||||
// the navigateLinkClick to complete. This navigation would trigger
|
||||
// RecordStatefulBounces if the protection was enabled. Give
|
||||
// RecordStatefulBounces time to run after navigation.
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
}
|
||||
await promiseRecordBounces;
|
||||
|
||||
Assert.deepEqual(
|
||||
bounceTrackingProtection
|
||||
@ -418,25 +393,11 @@ async function runTestBounce(options = {}) {
|
||||
// If the caller specified a function to run after the bounce, run it now.
|
||||
await postBounceCallback();
|
||||
|
||||
// Run tracker purging. If the feature is disabled this throws.
|
||||
let mode = Services.prefs.getIntPref("privacy.bounceTrackingProtection.mode");
|
||||
let expectPurgingToThrow =
|
||||
mode != Ci.nsIBounceTrackingProtection.MODE_ENABLED &&
|
||||
mode != Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN;
|
||||
|
||||
if (expectPurgingToThrow) {
|
||||
await Assert.rejects(
|
||||
bounceTrackingProtection.testRunPurgeBounceTrackers(),
|
||||
/NS_ERROR_NOT_AVAILABLE/,
|
||||
"testRunPurgeBounceTrackers should reject when BTP is disabled."
|
||||
);
|
||||
} else {
|
||||
Assert.deepEqual(
|
||||
await bounceTrackingProtection.testRunPurgeBounceTrackers(),
|
||||
expectPurge ? [SITE_TRACKER] : [],
|
||||
`Should ${expectPurge ? "" : "not "}purge state for ${SITE_TRACKER}.`
|
||||
);
|
||||
}
|
||||
Assert.deepEqual(
|
||||
await bounceTrackingProtection.testRunPurgeBounceTrackers(),
|
||||
expectPurge ? [SITE_TRACKER] : [],
|
||||
`Should ${expectPurge ? "" : "not "}purge state for ${SITE_TRACKER}.`
|
||||
);
|
||||
|
||||
// Clean up
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
@ -1,6 +1,6 @@
|
||||
[DEFAULT]
|
||||
prefs = [
|
||||
"privacy.bounceTrackingProtection.mode=1",
|
||||
"privacy.bounceTrackingProtection.enabled=true",
|
||||
"privacy.bounceTrackingProtection.enableTestMode=true",
|
||||
]
|
||||
|
||||
|
@ -28,11 +28,9 @@ add_setup(function () {
|
||||
* @param {bool} num - Number of hosts to purge
|
||||
*/
|
||||
async function testNumHostsPerPurgeRun(isDryRunMode, num) {
|
||||
Services.prefs.setIntPref(
|
||||
"privacy.bounceTrackingProtection.mode",
|
||||
Services.prefs.setBoolPref(
|
||||
"privacy.bounceTrackingProtection.enableDryRunMode",
|
||||
isDryRunMode
|
||||
? Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN
|
||||
: Ci.nsIBounceTrackingProtection.MODE_ENABLED
|
||||
);
|
||||
|
||||
Assert.equal(
|
||||
@ -71,7 +69,9 @@ async function testNumHostsPerPurgeRun(isDryRunMode, num) {
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
Services.prefs.clearUserPref("privacy.bounceTrackingProtection.mode");
|
||||
Services.prefs.clearUserPref(
|
||||
"privacy.bounceTrackingProtection.enableDryRunMode"
|
||||
);
|
||||
Services.fog.testResetFOG();
|
||||
btp.clearAll();
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
[DEFAULT]
|
||||
prefs = [
|
||||
"privacy.bounceTrackingProtection.mode=1",
|
||||
"privacy.bounceTrackingProtection.enabled=true",
|
||||
"privacy.bounceTrackingProtection.enableTestMode=true",
|
||||
"privacy.bounceTrackingProtection.bounceTrackingPurgeTimerPeriodSec=0",
|
||||
"privacy.bounceTrackingProtection.enableDryRunMode=false",
|
||||
]
|
||||
|
||||
["test_bouncetracking_clearExpiredUserActivation.js"]
|
||||
|
@ -40,9 +40,9 @@ XPCOMUtils.defineLazyServiceGetter(
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"bounceTrackingProtectionMode",
|
||||
"privacy.bounceTrackingProtection.mode",
|
||||
Ci.nsIBounceTrackingProtection.MODE_DISABLED
|
||||
"isBounceTrackingProtectionEnabled",
|
||||
"privacy.bounceTrackingProtection.enabled",
|
||||
false
|
||||
);
|
||||
|
||||
/**
|
||||
@ -1798,20 +1798,14 @@ const IdentityCredentialStorageCleaner = {
|
||||
|
||||
const BounceTrackingProtectionStateCleaner = {
|
||||
async deleteAll() {
|
||||
if (
|
||||
lazy.bounceTrackingProtectionMode ==
|
||||
Ci.nsIBounceTrackingProtection.MODE_DISABLED
|
||||
) {
|
||||
if (!lazy.isBounceTrackingProtectionEnabled) {
|
||||
return;
|
||||
}
|
||||
await lazy.bounceTrackingProtection.clearAll();
|
||||
},
|
||||
|
||||
async deleteByPrincipal(aPrincipal) {
|
||||
if (
|
||||
lazy.bounceTrackingProtectionMode ==
|
||||
Ci.nsIBounceTrackingProtection.MODE_DISABLED
|
||||
) {
|
||||
if (!lazy.isBounceTrackingProtectionEnabled) {
|
||||
return;
|
||||
}
|
||||
let { baseDomain, originAttributes } = aPrincipal;
|
||||
@ -1822,30 +1816,21 @@ const BounceTrackingProtectionStateCleaner = {
|
||||
},
|
||||
|
||||
async deleteByBaseDomain(aBaseDomain) {
|
||||
if (
|
||||
lazy.bounceTrackingProtectionMode ==
|
||||
Ci.nsIBounceTrackingProtection.MODE_DISABLED
|
||||
) {
|
||||
if (!lazy.isBounceTrackingProtectionEnabled) {
|
||||
return;
|
||||
}
|
||||
await lazy.bounceTrackingProtection.clearBySiteHost(aBaseDomain);
|
||||
},
|
||||
|
||||
async deleteByRange(aFrom, aTo) {
|
||||
if (
|
||||
lazy.bounceTrackingProtectionMode ==
|
||||
Ci.nsIBounceTrackingProtection.MODE_DISABLED
|
||||
) {
|
||||
if (!lazy.isBounceTrackingProtectionEnabled) {
|
||||
return;
|
||||
}
|
||||
await lazy.bounceTrackingProtection.clearByTimeRange(aFrom, aTo);
|
||||
},
|
||||
|
||||
async deleteByHost(aHost) {
|
||||
if (
|
||||
lazy.bounceTrackingProtectionMode ==
|
||||
Ci.nsIBounceTrackingProtection.MODE_DISABLED
|
||||
) {
|
||||
if (!lazy.isBounceTrackingProtectionEnabled) {
|
||||
return;
|
||||
}
|
||||
let baseDomain = getBaseDomainWithFallback(aHost);
|
||||
@ -1853,10 +1838,7 @@ const BounceTrackingProtectionStateCleaner = {
|
||||
},
|
||||
|
||||
async deleteByOriginAttributes(aOriginAttributesPatternString) {
|
||||
if (
|
||||
lazy.bounceTrackingProtectionMode ==
|
||||
Ci.nsIBounceTrackingProtection.MODE_DISABLED
|
||||
) {
|
||||
if (!lazy.isBounceTrackingProtectionEnabled) {
|
||||
return;
|
||||
}
|
||||
await lazy.bounceTrackingProtection.clearByOriginAttributesPattern(
|
||||
|
@ -3423,11 +3423,21 @@ bounceTrackingProtection:
|
||||
hasExposure: false
|
||||
variables:
|
||||
enabled:
|
||||
type: int
|
||||
type: boolean
|
||||
setPref:
|
||||
branch: default
|
||||
pref: privacy.bounceTrackingProtection.mode
|
||||
description: Mode to run the feature in. See nsIBounceTrackingProtection.idl for documentation.
|
||||
pref: privacy.bounceTrackingProtection.enabled
|
||||
description: Main flag to enable / disable the feature.
|
||||
enableDryRunMode:
|
||||
type: boolean
|
||||
setPref:
|
||||
branch: default
|
||||
pref: privacy.bounceTrackingProtection.enableDryRunMode
|
||||
description: >-
|
||||
Enables a mode where if bounce tracking protection is enabled it
|
||||
classifies but does not purge trackers. This mode is helpful for testing
|
||||
the feature without risking data loss. Telemetry is still collected
|
||||
normally.
|
||||
|
||||
remoteTabManagement:
|
||||
description: >
|
||||
|
@ -1,13 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
# Message which is shown when Bounce Tracking Protection has detected site as a
|
||||
# bounce tracker. Do not translate "bounce tracker".
|
||||
# Variables:
|
||||
# $siteHost (string): The host portion of the site which has been classified as a tracker.
|
||||
# $gracePeriodSeconds (number): Grace period window in seconds until the site purged (clearing cookies, storages and caches).
|
||||
btp-warning-tracker-classified =
|
||||
{ $gracePeriodSeconds ->
|
||||
*[other] “{ $siteHost }” has been classified as a bounce tracker. If it does not receive user activation within the next { $gracePeriodSeconds } seconds it will have its state purged.
|
||||
}
|
Loading…
Reference in New Issue
Block a user