summaryrefslogtreecommitdiffstats
path: root/toolkit/components/resistfingerprinting/nsRFPService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/resistfingerprinting/nsRFPService.cpp')
-rw-r--r--toolkit/components/resistfingerprinting/nsRFPService.cpp126
1 files changed, 111 insertions, 15 deletions
diff --git a/toolkit/components/resistfingerprinting/nsRFPService.cpp b/toolkit/components/resistfingerprinting/nsRFPService.cpp
index 643cc2cb7a..f39deb3283 100644
--- a/toolkit/components/resistfingerprinting/nsRFPService.cpp
+++ b/toolkit/components/resistfingerprinting/nsRFPService.cpp
@@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "nsRFPService.h"
@@ -19,6 +19,7 @@
#include "MainThreadUtils.h"
#include "ScopedNSSTypes.h"
+#include "mozilla/AntiTrackingUtils.h"
#include "mozilla/ArrayIterator.h"
#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
@@ -109,6 +110,8 @@ static mozilla::LazyLogModule gFingerprinterDetection("FingerprinterDetection");
#define LAST_PB_SESSION_EXITED_TOPIC "last-pb-context-exited"
#define IDLE_TOPIC "browser-idle-startup-tasks-finished"
#define GFX_FEATURES "gfx-features-ready"
+#define USER_CHARACTERISTICS_TEST_REQUEST \
+ "user-characteristics-testing-please-populate-data"
static constexpr uint32_t kVideoFramesPerSec = 30;
static constexpr uint32_t kVideoDroppedRatio = 5;
@@ -190,6 +193,9 @@ nsresult nsRFPService::Init() {
rv = obs->AddObserver(this, GFX_FEATURES, false);
NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = obs->AddObserver(this, USER_CHARACTERISTICS_TEST_REQUEST, false);
+ NS_ENSURE_SUCCESS(rv, rv);
}
Preferences::RegisterCallbacks(nsRFPService::PrefChanged, gCallbackPrefs,
@@ -289,6 +295,7 @@ void nsRFPService::StartShutdown() {
obs->RemoveObserver(this, OBSERVER_TOPIC_IDLE_DAILY);
obs->RemoveObserver(this, IDLE_TOPIC);
obs->RemoveObserver(this, GFX_FEATURES);
+ obs->RemoveObserver(this, USER_CHARACTERISTICS_TEST_REQUEST);
}
}
@@ -350,6 +357,12 @@ nsRFPService::Observe(nsISupports* aObject, const char* aTopic,
}
}
+ if (!strcmp(USER_CHARACTERISTICS_TEST_REQUEST, aTopic) &&
+ xpc::IsInAutomation()) {
+ nsUserCharacteristics::PopulateDataAndEventuallySubmit(
+ /* aUpdatePref = */ false, /* aTesting = */ true);
+ }
+
if (!strcmp(OBSERVER_TOPIC_IDLE_DAILY, aTopic)) {
if (StaticPrefs::
privacy_resistFingerprinting_randomization_daily_reset_enabled()) {
@@ -1267,7 +1280,10 @@ Maybe<nsTArray<uint8_t>> nsRFPService::GenerateKey(nsIChannel* aChannel) {
// Set the partitionKey using the top level URI to ensure that the key is
// specific to the top level site.
- attrs.SetPartitionKey(topLevelURI);
+ bool foreignByAncestorContext =
+ AntiTrackingUtils::IsThirdPartyChannel(aChannel) &&
+ loadInfo->GetIsThirdPartyContextToTopWindow();
+ attrs.SetPartitionKey(topLevelURI, foreignByAncestorContext);
nsAutoCString oaSuffix;
attrs.CreateSuffix(oaSuffix);
@@ -1337,8 +1353,14 @@ nsRFPService::CleanRandomKeyByPrincipal(nsIPrincipal* aPrincipal) {
OriginAttributes attrs = aPrincipal->OriginAttributesRef();
nsCOMPtr<nsIURI> uri = aPrincipal->GetURI();
- attrs.SetPartitionKey(uri);
+ attrs.SetPartitionKey(uri, false);
+ ClearBrowsingSessionKey(attrs);
+
+ // We must also include the cross-site embeds of this principal that end up
+ // re-embedded back into the same principal's top level, otherwise state will
+ // persist for this target
+ attrs.SetPartitionKey(uri, true);
ClearBrowsingSessionKey(attrs);
return NS_OK;
}
@@ -1354,14 +1376,21 @@ nsRFPService::CleanRandomKeyByDomain(const nsACString& aDomain) {
// Use the originAttributes to get the partitionKey.
OriginAttributes attrs;
- attrs.SetPartitionKey(httpURI);
+ attrs.SetPartitionKey(httpURI, false);
// Create a originAttributesPattern and set the http partitionKey to the
// pattern.
OriginAttributesPattern pattern;
pattern.mPartitionKey.Reset();
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
+ ClearBrowsingSessionKey(pattern);
+ // We must also include the cross-site embeds of this principal that end up
+ // re-embedded back into the same principal's top level, otherwise state will
+ // persist for this target
+ attrs.SetPartitionKey(httpURI, true);
+ pattern.mPartitionKey.Reset();
+ pattern.mPartitionKey.Construct(attrs.mPartitionKey);
ClearBrowsingSessionKey(pattern);
// Get https URI from the domain.
@@ -1370,10 +1399,17 @@ nsRFPService::CleanRandomKeyByDomain(const nsACString& aDomain) {
NS_ENSURE_SUCCESS(rv, rv);
// Use the originAttributes to get the partitionKey and set to the pattern.
- attrs.SetPartitionKey(httpsURI);
+ attrs.SetPartitionKey(httpsURI, false);
pattern.mPartitionKey.Reset();
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
+ ClearBrowsingSessionKey(pattern);
+ // We must also include the cross-site embeds of this principal that end up
+ // re-embedded back into the same principal's top level, otherwise state will
+ // persist for this target
+ attrs.SetPartitionKey(httpsURI, true);
+ pattern.mPartitionKey.Reset();
+ pattern.mPartitionKey.Construct(attrs.mPartitionKey);
ClearBrowsingSessionKey(pattern);
return NS_OK;
}
@@ -1395,7 +1431,7 @@ nsRFPService::CleanRandomKeyByHost(const nsACString& aHost,
// Use the originAttributes to get the partitionKey.
OriginAttributes attrs;
- attrs.SetPartitionKey(httpURI);
+ attrs.SetPartitionKey(httpURI, false);
// Set the partitionKey to the pattern.
pattern.mPartitionKey.Reset();
@@ -1403,16 +1439,31 @@ nsRFPService::CleanRandomKeyByHost(const nsACString& aHost,
ClearBrowsingSessionKey(pattern);
+ // We must also include the cross-site embeds of this principal that end up
+ // re-embedded back into the same principal's top level, otherwise state will
+ // persist for this target
+ attrs.SetPartitionKey(httpURI, true);
+ pattern.mPartitionKey.Reset();
+ pattern.mPartitionKey.Construct(attrs.mPartitionKey);
+ ClearBrowsingSessionKey(pattern);
+
// Get https URI from the host.
nsCOMPtr<nsIURI> httpsURI;
rv = NS_NewURI(getter_AddRefs(httpsURI), "https://"_ns + aHost);
NS_ENSURE_SUCCESS(rv, rv);
// Use the originAttributes to get the partitionKey and set to the pattern.
- attrs.SetPartitionKey(httpsURI);
+ attrs.SetPartitionKey(httpsURI, false);
pattern.mPartitionKey.Reset();
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
+ ClearBrowsingSessionKey(pattern);
+ // We must also include the cross-site embeds of this principal that end up
+ // re-embedded back into the same principal's top level, otherwise state will
+ // persist for this target
+ attrs.SetPartitionKey(httpsURI, true);
+ pattern.mPartitionKey.Reset();
+ pattern.mPartitionKey.Construct(attrs.mPartitionKey);
ClearBrowsingSessionKey(pattern);
return NS_OK;
}
@@ -2011,19 +2062,63 @@ Maybe<RFPTarget> nsRFPService::GetOverriddenFingerprintingSettingsForChannel(
}
// The channel is for the first-party load.
- if (!loadInfo->GetIsThirdPartyContextToTopWindow()) {
+ if (!AntiTrackingUtils::IsThirdPartyChannel(aChannel)) {
return GetOverriddenFingerprintingSettingsForURI(uri, nullptr);
}
// The channel is for the third-party load. We get the first-party URI from
// the top-level window global parent.
- RefPtr<dom::WindowGlobalParent> topWGP =
- bc->Top()->Canonical()->GetCurrentWindowGlobal();
+ RefPtr<dom::CanonicalBrowsingContext> topBC = bc->Top()->Canonical();
+ RefPtr<dom::WindowGlobalParent> topWGP = topBC->GetCurrentWindowGlobal();
if (NS_WARN_IF(!topWGP)) {
return Nothing();
}
+ nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
+ DebugOnly<nsresult> rv =
+ loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ MOZ_ASSERT(cookieJarSettings);
+
+ uint64_t topWindowContextIdFromCJS =
+ net::CookieJarSettings::Cast(cookieJarSettings)
+ ->GetTopLevelWindowContextId();
+
+ // The top-level window could be navigated away when we get the fingerprinting
+ // override here. For example, the beacon requests. In this case, the
+ // top-level windowContext id won't match the inner window id of the top-level
+ // windowGlobalParent. So, we cannot rely on the URI from the top-level
+ // windowGlobalParent because it could be different from the one that creates
+ // the channel. Instead, we fallback to use the partitionKey in the
+ // cookieJarSettings to get the top-level URI.
+ if (topWGP->InnerWindowId() != topWindowContextIdFromCJS) {
+ nsAutoString partitionKey;
+ rv = cookieJarSettings->GetPartitionKey(partitionKey);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+ // Bail out early if the partitionKey is empty.
+ if (partitionKey.IsEmpty()) {
+ return Nothing();
+ }
+
+ nsAutoString scheme;
+ nsAutoString domain;
+ int32_t unused;
+ bool unused2;
+ if (!OriginAttributes::ParsePartitionKey(partitionKey, scheme, domain,
+ unused, unused2)) {
+ MOZ_ASSERT(false);
+ return Nothing();
+ }
+
+ nsCOMPtr<nsIURI> topURI;
+ rv = NS_NewURI(getter_AddRefs(topURI), scheme + u"://"_ns + domain);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+ return GetOverriddenFingerprintingSettingsForURI(topURI, uri);
+ }
+
nsCOMPtr<nsIPrincipal> topPrincipal = topWGP->DocumentPrincipal();
if (NS_WARN_IF(!topPrincipal)) {
return Nothing();
@@ -2049,19 +2144,20 @@ Maybe<RFPTarget> nsRFPService::GetOverriddenFingerprintingSettingsForChannel(
#ifdef DEBUG
// Verify if the top URI matches the partitionKey of the channel.
- nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
- Unused << loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
-
nsAutoString partitionKey;
cookieJarSettings->GetPartitionKey(partitionKey);
OriginAttributes attrs;
- attrs.SetPartitionKey(topURI);
+ attrs.SetPartitionKey(topURI, false);
+
+ OriginAttributes attrsForeignByAncestor;
+ attrsForeignByAncestor.SetPartitionKey(topURI, true);
// The partitionKey of the channel could haven't been set here if the loading
// channel is top-level.
MOZ_ASSERT_IF(!partitionKey.IsEmpty(),
- attrs.mPartitionKey.Equals(partitionKey));
+ attrs.mPartitionKey.Equals(partitionKey) ||
+ attrsForeignByAncestor.mPartitionKey.Equals(partitionKey));
#endif
return GetOverriddenFingerprintingSettingsForURI(topURI, uri);