Bug 1877419 - Part 1: Added nested stripping of urls to copy without site tracking. r=pbz,necko-reviewers

Depends on D204914

Differential Revision: https://phabricator.services.mozilla.com/D202943
This commit is contained in:
abhishekmadan30 2024-03-28 18:02:16 +00:00
parent 6118a3b4b6
commit 6aaa10473d
4 changed files with 113 additions and 56 deletions

View file

@ -1302,9 +1302,7 @@ void URLParams::ParseInput(const nsACString& aInput) {
});
}
namespace {
void SerializeString(const nsCString& aInput, nsAString& aValue) {
void URLParams::SerializeString(const nsCString& aInput, nsAString& aValue) {
const unsigned char* p = (const unsigned char*)aInput.get();
const unsigned char* end = p + aInput.Length();
@ -1325,8 +1323,6 @@ void SerializeString(const nsCString& aInput, nsAString& aValue) {
}
}
} // namespace
void URLParams::Serialize(nsAString& aValue, bool aEncode) const {
aValue.Truncate();
bool first = true;

View file

@ -308,6 +308,8 @@ class URLParams final {
*/
void Serialize(nsAString& aValue, bool aEncode) const;
static void SerializeString(const nsCString& aInput, nsAString& aValue);
void Get(const nsAString& aName, nsString& aRetval);
void GetAll(const nsAString& aName, nsTArray<nsString>& aRetval);
@ -338,6 +340,8 @@ class URLParams final {
uint32_t Length() const { return mParams.Length(); }
static void DecodeString(const nsACString& aInput, nsAString& aOutput);
const nsAString& GetKeyAtIndex(uint32_t aIndex) const {
MOZ_ASSERT(aIndex < mParams.Length());
return mParams[aIndex].mKey;
@ -355,7 +359,6 @@ class URLParams final {
void Sort();
private:
static void DecodeString(const nsACString& aInput, nsAString& aOutput);
static void ConvertString(const nsACString& aInput, nsAString& aOutput);
static bool ParseNextInternal(const char*& aStart, const char* aEnd,
bool aShouldDecode, nsAString* aOutputName,

View file

@ -17,6 +17,7 @@
#include "nsIURIMutator.h"
#include "nsUnicharUtils.h"
#include "nsURLHelper.h"
#include "nsNetUtil.h"
#include "mozilla/dom/StripOnShareRuleBinding.h"
namespace {
@ -84,50 +85,9 @@ URLQueryStringStripper::StripForCopyOrShare(nsIURI* aURI,
NS_ENSURE_ARG_POINTER(strippedURI);
int aStripCount = 0;
nsAutoCString query;
nsresult rv = aURI->GetQuery(query);
nsresult rv =
StripForCopyOrShareInternal(aURI, strippedURI, aStripCount, false);
NS_ENSURE_SUCCESS(rv, rv);
// We don't need to do anything if there is no query string.
if (query.IsEmpty()) {
Telemetry::Accumulate(Telemetry::STRIP_ON_SHARE_PARAMS_REMOVED, 0);
return NS_OK;
}
nsAutoCString host;
rv = aURI->GetHost(host);
NS_ENSURE_SUCCESS(rv, rv);
URLParams params;
URLParams::Parse(query, true, [&](nsString&& name, nsString&& value) {
nsAutoString lowerCaseName;
ToLowerCase(name, lowerCaseName);
// Look through the global rules.
dom::StripRule globalRule;
bool keyExists = mStripOnShareMap.Get("*"_ns, &globalRule);
// There should always be a global rule.
MOZ_ASSERT(keyExists);
for (const auto& param : globalRule.mQueryParams) {
if (param == lowerCaseName) {
aStripCount++;
return true;
}
}
// Check for site specific rules.
dom::StripRule siteSpecificRule;
keyExists = mStripOnShareMap.Get(host, &siteSpecificRule);
if (keyExists) {
for (const auto& param : siteSpecificRule.mQueryParams) {
if (param == lowerCaseName) {
aStripCount++;
return true;
}
}
}
params.Append(name, value);
return true;
});
Telemetry::Accumulate(Telemetry::STRIP_ON_SHARE_PARAMS_REMOVED, aStripCount);
@ -135,13 +95,6 @@ URLQueryStringStripper::StripForCopyOrShare(nsIURI* aURI,
return NS_OK;
}
nsAutoString newQuery;
params.Serialize(newQuery, false);
Unused << NS_MutateURI(aURI)
.SetQuery(NS_ConvertUTF16toUTF8(newQuery))
.Finalize(strippedURI);
// To calculate difference in length of the URL
// after stripping occurs for Telemetry
nsAutoCString specOriginalURI;
@ -426,4 +379,103 @@ URLQueryStringStripper::Observe(nsISupports*, const char* aTopic,
return NS_OK;
}
nsresult URLQueryStringStripper::StripForCopyOrShareInternal(
nsIURI* aURI, nsIURI** strippedURI, int& aStripCount,
bool aStripNestedURIs) {
nsAutoCString query;
nsresult rv = aURI->GetQuery(query);
NS_ENSURE_SUCCESS(rv, rv);
// We don't need to do anything if there is no query string.
if (query.IsEmpty()) {
Telemetry::Accumulate(Telemetry::STRIP_ON_SHARE_PARAMS_REMOVED, 0);
return NS_OK;
}
nsAutoCString host;
rv = aURI->GetHost(host);
NS_ENSURE_SUCCESS(rv, rv);
URLParams params;
URLParams::Parse(query, false, [&](nsString&& name, nsString&& value) {
nsAutoString lowerCaseName;
ToLowerCase(name, lowerCaseName);
// Look through the global rules.
dom::StripRule globalRule;
bool keyExists = mStripOnShareMap.Get("*"_ns, &globalRule);
// There should always be a global rule.
MOZ_ASSERT(keyExists);
// Look through the global rules.
for (const auto& param : globalRule.mQueryParams) {
if (param == lowerCaseName) {
aStripCount++;
return true;
}
}
// Check for site specific rules.
dom::StripRule siteSpecificRule;
keyExists = mStripOnShareMap.Get(host, &siteSpecificRule);
if (keyExists) {
for (const auto& param : siteSpecificRule.mQueryParams) {
if (param == lowerCaseName) {
aStripCount++;
return true;
}
}
}
// Only if it is top layer of the recursion then it
// checks if the value of the query parameter is a valid URI
// if not then it gets added back to the query, if it is then
// it gets passed back into this method but with the recursive
// stripping flag set to true
if (!aStripNestedURIs) {
nsAutoString decodeValue;
URLParams::DecodeString(NS_ConvertUTF16toUTF8(value), decodeValue);
nsCOMPtr<nsIURI> nestedURI;
rv = NS_NewURI(getter_AddRefs(nestedURI), decodeValue);
if (NS_WARN_IF(NS_FAILED(rv))) {
params.Append(name, value);
return true;
}
nsCOMPtr<nsIURI> strippedNestedURI;
rv = StripForCopyOrShareInternal(
nestedURI, getter_AddRefs(strippedNestedURI), aStripCount, true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
nsAutoCString nestedURIString;
rv = strippedNestedURI->GetSpec(nestedURIString);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
// Encodes URI
nsAutoString encodedURI;
URLParams::SerializeString(nestedURIString, encodedURI);
params.Append(name, encodedURI);
return true;
}
params.Append(name, value);
return true;
});
nsAutoString newQuery;
params.Serialize(newQuery, false);
return NS_MutateURI(aURI)
.SetQuery(NS_ConvertUTF16toUTF8(newQuery))
.Finalize(strippedURI);
}
} // namespace mozilla

View file

@ -49,6 +49,12 @@ class URLQueryStringStripper final : public nsIObserver,
void PopulateStripList(const nsAString& aList);
void PopulateAllowList(const nsACString& aList);
// Recursive helper function that helps strip URIs of tracking parameters
// and enables the stripping of tracking paramerters that are in a URI which
// is nested in a query parameter
nsresult StripForCopyOrShareInternal(nsIURI* aURI, nsIURI** strippedURI,
int& aStripCount, bool aStripNestedURIs);
nsTHashSet<nsString> mList;
nsTHashSet<nsCString> mAllowList;
nsCOMPtr<nsIURLQueryStrippingListService> mListService;