1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #ifndef mozilla_BounceTrackingProtection_h__
5 #define mozilla_BounceTrackingProtection_h__
7 #include "BounceTrackingMapEntry.h"
8 #include "BounceTrackingStorageObserver.h"
9 #include "mozilla/Logging.h"
10 #include "mozilla/MozPromise.h"
11 #include "nsIBounceTrackingProtection.h"
12 #include "nsIBTPRemoteExceptionList.h"
13 #include "mozilla/Maybe.h"
14 #include "nsIObserver.h"
15 #include "nsWeakReference.h"
16 #include "nsTHashSet.h"
23 class BounceTrackingAllowList
;
24 class BounceTrackingState
;
25 class BounceTrackingStateGlobal
;
26 class BounceTrackingProtectionStorage
;
27 class ClearDataCallback
;
28 class OriginAttributes
;
31 class CanonicalBrowsingContext
;
33 class WindowGlobalParent
;
36 using ClearDataMozPromise
=
37 MozPromise
<RefPtr
<BounceTrackingPurgeEntry
>, uint32_t, true>;
39 extern LazyLogModule gBounceTrackingProtectionLog
;
41 class BounceTrackingProtection final
: public nsIBounceTrackingProtection
,
43 public nsSupportsWeakReference
{
46 NS_DECL_NSIBOUNCETRACKINGPROTECTION
49 static already_AddRefed
<BounceTrackingProtection
> GetSingleton();
51 // Record telemetry about which mode the feature is in.
52 static void RecordModePrefTelemetry();
54 // This algorithm is called when detecting the end of an extended navigation.
55 // This could happen if a user-initiated navigation is detected in process
56 // navigation start for bounce tracking, or if the client bounce detection
57 // timer expires after process response received for bounce tracking without
58 // observing a client redirect.
59 [[nodiscard
]] nsresult
RecordStatefulBounces(
60 BounceTrackingState
* aBounceTrackingState
);
62 // Stores a user activation flag with a timestamp for the given principal. The
63 // timestamp defaults to the current time, but can be overridden via
64 // aActivationTime. If aWindowContext is provided, this will add the
65 // given principal's activation to the extended navigation's
66 // BounceTrackingRecord as well.
67 // Parent process only. Prefer the WindowContext variant if possible.
68 [[nodiscard
]] static nsresult
RecordUserActivation(
69 nsIPrincipal
* aPrincipal
, Maybe
<PRTime
> aActivationTime
= Nothing(),
70 dom::CanonicalBrowsingContext
* aTopBrowsingContext
= nullptr);
72 // Same as above but can be called from any process given a WindowContext.
73 // Gecko callers should prefer this method because it takes care of IPC and
74 // gets the principal user activation. IPC messages from the content to parent
75 // passing a principal should be avoided for security reasons. aActivationTime
76 // defaults to PR_Now().
77 [[nodiscard
]] static nsresult
RecordUserActivation(
78 dom::WindowContext
* aWindowContext
);
80 // Clears expired user interaction flags for the given state global. If
81 // aStateGlobal == nullptr, clears expired user interaction flags for all
83 [[nodiscard
]] nsresult
ClearExpiredUserInteractions(
84 BounceTrackingStateGlobal
* aStateGlobal
= nullptr);
86 // Logs a warning to the DevTools website console if we recently purged a site
87 // matching the given principal. Purge log data is not persisted across
88 // restarts so we only know whether a purge happened during this session. For
89 // private browsing mode closing the last private browsing window clears purge
91 void MaybeLogPurgedWarningForSite(nsIPrincipal
* aPrincipal
,
92 BounceTrackingState
* aBounceTrackingState
);
95 BounceTrackingProtection() = default;
96 ~BounceTrackingProtection() = default;
98 // Initializes the singleton instance of BounceTrackingProtection.
99 [[nodiscard
]] nsresult
Init();
101 // Listens for feature pref changes and enables / disables BTP.
102 static void OnPrefChange(const char* aPref
, void* aData
);
104 // Called by OnPrefChange when the mode pref changes.
105 // isStartup indicates whether this is the initial mode change after startup.
106 nsresult
OnModeChange(bool aIsStartup
);
108 // Schedules or cancels the periodic bounce tracker purging. If this method is
109 // called while purging is already scheduled it will cancel the existing timer
110 // and then start a new timer.
111 nsresult
UpdateBounceTrackingPurgeTimer(bool aShouldEnable
);
113 // Flag to ensure we only call into glean telemetry when the feature mode
115 static Maybe
<uint32_t> sLastRecordedModeTelemetry
;
117 // Timer which periodically runs PurgeBounceTrackers.
118 nsCOMPtr
<nsITimer
> mBounceTrackingPurgeTimer
;
120 // Used to notify BounceTrackingState of storage and cookie access.
121 RefPtr
<BounceTrackingStorageObserver
> mStorageObserver
;
123 // Storage for user agent globals.
124 RefPtr
<BounceTrackingProtectionStorage
> mStorage
;
126 // Interface to remote settings exception list.
127 nsCOMPtr
<nsIBTPRemoteExceptionList
> mRemoteExceptionList
;
128 RefPtr
<GenericNonExclusivePromise
> mRemoteExceptionListInitPromise
;
130 // In-memory copy of the remote settings exception list.
131 nsTHashSet
<nsCStringHashKey
> mRemoteSiteHostExceptions
;
133 // Lazily initializes the remote exception list.
134 RefPtr
<GenericNonExclusivePromise
> EnsureRemoteExceptionListService();
136 // Clear state for classified bounce trackers. To be called on an interval.
137 using PurgeBounceTrackersMozPromise
=
138 MozPromise
<nsTArray
<RefPtr
<BounceTrackingPurgeEntry
>>, nsresult
, true>;
139 RefPtr
<PurgeBounceTrackersMozPromise
> PurgeBounceTrackers();
141 // Report purged trackers to the anti-tracking database via
142 // nsITrackingDBService.
143 static void ReportPurgedTrackersToAntiTrackingDB(
144 const nsTArray
<RefPtr
<BounceTrackingPurgeEntry
>>& aPurgedSiteHosts
);
146 // Clear state for classified bounce trackers for a specific state global.
147 // aClearPromises is populated with promises for each host that is cleared.
148 [[nodiscard
]] nsresult
PurgeBounceTrackersForStateGlobal(
149 BounceTrackingStateGlobal
* aStateGlobal
,
150 BounceTrackingAllowList
& aBounceTrackingAllowList
,
151 nsTArray
<RefPtr
<ClearDataMozPromise
>>& aClearPromises
);
153 // Helper which calls nsIClearDataService to clear data for given host and
155 // After a successful call aClearPromise will be populated.
156 [[nodiscard
]] nsresult
PurgeStateForHostAndOriginAttributes(
157 const nsACString
& aHost
, PRTime bounceTime
,
158 const OriginAttributes
& aOriginAttributes
,
159 ClearDataMozPromise
** aClearPromise
);
161 // Whether a purge operation is currently in progress. This avoids running
162 // multiple purge operations at the same time.
163 bool mPurgeInProgress
= false;
165 // Imports user activation permissions from permission manager if needed. This
166 // is important so we don't purge data for sites the user has interacted with
167 // before the feature was enabled.
168 [[nodiscard
]] nsresult
MaybeMigrateUserInteractionPermissions();
170 // Log a warning about the classification of a site as a bounce tracker. The
171 // message is logged to the devtools console aBounceTrackingState is
173 [[nodiscard
]] static nsresult
LogBounceTrackersClassifiedToWebConsole(
174 BounceTrackingState
* aBounceTrackingState
,
175 const nsTArray
<nsCString
>& aSiteHosts
);
177 // Comparator for sorting purge log entries by purge timestamp.
178 class PurgeEntryTimeComparator
{
180 bool Equals(const BounceTrackingPurgeEntry
* a
,
181 const BounceTrackingPurgeEntry
* b
) const {
183 return a
->PurgeTimeRefConst() == b
->PurgeTimeRefConst();
186 bool LessThan(const BounceTrackingPurgeEntry
* a
,
187 const BounceTrackingPurgeEntry
* b
) const {
189 return a
->PurgeTimeRefConst() < b
->PurgeTimeRefConst();
194 } // namespace mozilla