diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /toolkit/components/antitracking/URLQueryStringStripper.cpp | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/antitracking/URLQueryStringStripper.cpp')
-rw-r--r-- | toolkit/components/antitracking/URLQueryStringStripper.cpp | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/URLQueryStringStripper.cpp b/toolkit/components/antitracking/URLQueryStringStripper.cpp new file mode 100644 index 0000000000..581b8fcdfb --- /dev/null +++ b/toolkit/components/antitracking/URLQueryStringStripper.cpp @@ -0,0 +1,179 @@ +/* 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 "URLQueryStringStripper.h" + +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/StaticPrefs_privacy.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/Unused.h" +#include "mozilla/Telemetry.h" + +#include "nsEffectiveTLDService.h" +#include "nsISupportsImpl.h" +#include "nsIURI.h" +#include "nsIURIMutator.h" +#include "nsUnicharUtils.h" +#include "nsURLHelper.h" + +namespace { +mozilla::StaticRefPtr<mozilla::URLQueryStringStripper> gQueryStringStripper; +} // namespace + +namespace mozilla { + +NS_IMPL_ISUPPORTS(URLQueryStringStripper, nsIURLQueryStrippingListObserver) + +URLQueryStringStripper* URLQueryStringStripper::GetOrCreate() { + if (!gQueryStringStripper) { + gQueryStringStripper = new URLQueryStringStripper(); + gQueryStringStripper->Init(); + + RunOnShutdown( + [&] { + gQueryStringStripper->Shutdown(); + gQueryStringStripper = nullptr; + }, + ShutdownPhase::XPCOMShutdown); + } + + return gQueryStringStripper; +} + +/* static */ +uint32_t URLQueryStringStripper::Strip(nsIURI* aURI, bool aIsPBM, + nsCOMPtr<nsIURI>& aOutput) { + if (aIsPBM) { + if (!StaticPrefs::privacy_query_stripping_enabled_pbmode()) { + return 0; + } + } else { + if (!StaticPrefs::privacy_query_stripping_enabled()) { + return 0; + } + } + + RefPtr<URLQueryStringStripper> stripper = GetOrCreate(); + + if (stripper->CheckAllowList(aURI)) { + return 0; + } + + return stripper->StripQueryString(aURI, aOutput); +} + +void URLQueryStringStripper::Init() { + mService = do_GetService("@mozilla.org/query-stripping-list-service;1"); + NS_ENSURE_TRUE_VOID(mService); + + mService->Init(); + mService->RegisterAndRunObserver(this); +} + +void URLQueryStringStripper::Shutdown() { + mList.Clear(); + mAllowList.Clear(); + + mService->UnregisterObserver(this); + mService = nullptr; +} + +uint32_t URLQueryStringStripper::StripQueryString(nsIURI* aURI, + nsCOMPtr<nsIURI>& aOutput) { + MOZ_ASSERT(aURI); + + nsCOMPtr<nsIURI> uri(aURI); + + nsAutoCString query; + nsresult rv = aURI->GetQuery(query); + NS_ENSURE_SUCCESS(rv, false); + + uint32_t numStripped = 0; + + // We don't need to do anything if there is no query string. + if (query.IsEmpty()) { + return numStripped; + } + + URLParams params; + + URLParams::Parse(query, [&](nsString&& name, nsString&& value) { + nsAutoString lowerCaseName; + + ToLowerCase(name, lowerCaseName); + + if (mList.Contains(lowerCaseName)) { + numStripped += 1; + + // Count how often a specific query param is stripped. For privacy reasons + // this will only count query params listed in the Histogram definition. + // Calls for any other query params will be discarded. + nsAutoCString telemetryLabel("param_"); + AppendUTF16toUTF8(lowerCaseName, telemetryLabel); + Telemetry::AccumulateCategorical( + Telemetry::QUERY_STRIPPING_COUNT_BY_PARAM, telemetryLabel); + + return true; + } + + params.Append(name, value); + return true; + }); + + // Return if there is no parameter has been stripped. + if (!numStripped) { + return numStripped; + } + + nsAutoString newQuery; + params.Serialize(newQuery, false); + + Unused << NS_MutateURI(uri) + .SetQuery(NS_ConvertUTF16toUTF8(newQuery)) + .Finalize(aOutput); + + return numStripped; +} + +bool URLQueryStringStripper::CheckAllowList(nsIURI* aURI) { + MOZ_ASSERT(aURI); + + // Get the site(eTLD+1) from the URI. + nsAutoCString baseDomain; + nsresult rv = + nsEffectiveTLDService::GetInstance()->GetBaseDomain(aURI, 0, baseDomain); + if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) { + return false; + } + NS_ENSURE_SUCCESS(rv, false); + + return mAllowList.Contains(baseDomain); +} + +void URLQueryStringStripper::PopulateStripList(const nsAString& aList) { + mList.Clear(); + + for (const nsAString& item : aList.Split(' ')) { + mList.Insert(item); + } +} + +void URLQueryStringStripper::PopulateAllowList(const nsACString& aList) { + mAllowList.Clear(); + + for (const nsACString& item : aList.Split(',')) { + mAllowList.Insert(item); + } +} + +NS_IMETHODIMP +URLQueryStringStripper::OnQueryStrippingListUpdate( + const nsAString& aStripList, const nsACString& aAllowList) { + PopulateStripList(aStripList); + PopulateAllowList(aAllowList); + return NS_OK; +} + +} // namespace mozilla |