Bug 1840385 - Do not spoof the OS in HTTP User Agent. r=tjr

Differential Revision: https://phabricator.services.mozilla.com/D234835
This commit is contained in:
Pier Angelo Vendrame
2025-01-24 16:08:27 +00:00
parent b889d58186
commit eb2f90f870
6 changed files with 29 additions and 82 deletions

View File

@@ -81,20 +81,13 @@ const DEFAULT_UA_OS = {
other: "X11; Linux x86_64",
};
const SPOOFED_UA_NAVIGATOR_OS = {
const SPOOFED_UA_OS = {
linux: "X11; Linux x86_64",
win: "Windows NT 10.0; Win64; x64",
macosx: "Macintosh; Intel Mac OS X 10.15",
android: "Android 10; Mobile",
other: "X11; Linux x86_64",
};
const SPOOFED_UA_HTTPHEADER_OS = {
linux: "Windows NT 10.0; Win64; x64",
win: "Windows NT 10.0; Win64; x64",
macosx: "Windows NT 10.0; Win64; x64",
android: "Android 10; Mobile",
other: "Windows NT 10.0; Win64; x64",
};
const SPOOFED_HW_CONCURRENCY = 2;
const CONST_APPCODENAME = "Mozilla";
@@ -143,7 +136,7 @@ async function testUserAgentHeader() {
is(
result,
expectedResults.userAgentHeader,
expectedResults.userAgent,
`Checking ${expectedResults.testDesc} User Agent HTTP Header.`
);
@@ -177,7 +170,7 @@ async function testNavigator() {
);
is(
result.userAgent,
expectedResults.userAgentNavigator,
expectedResults.userAgent,
`Checking ${testDesc} navigator.userAgent.`
);
is(
@@ -282,7 +275,7 @@ async function testWorkerNavigator() {
);
is(
result.userAgent,
expectedResults.userAgentNavigator,
expectedResults.userAgent,
`Checking ${testDesc} worker navigator.userAgent.`
);
is(
@@ -338,8 +331,7 @@ add_task(async function setupDefaultUserAgent() {
oscpu: DEFAULT_OSCPU[AppConstants.platform],
platform: DEFAULT_PLATFORM[AppConstants.platform],
pluginsLength: 5,
userAgentNavigator: defaultUserAgent,
userAgentHeader: defaultUserAgent,
userAgent: defaultUserAgent,
};
await testNavigator();
@@ -372,8 +364,7 @@ add_task(async function setupRFPExemptions() {
oscpu: DEFAULT_OSCPU[AppConstants.platform],
platform: DEFAULT_PLATFORM[AppConstants.platform],
pluginsLength: 5,
userAgentNavigator: defaultUserAgent,
userAgentHeader: defaultUserAgent,
userAgent: defaultUserAgent,
};
await testNavigator();
@@ -422,8 +413,7 @@ add_task(async function setupETPToggleExemptions() {
oscpu: DEFAULT_OSCPU[AppConstants.platform],
platform: DEFAULT_PLATFORM[AppConstants.platform],
pluginsLength: 5,
userAgentNavigator: defaultUserAgent,
userAgentHeader: defaultUserAgent,
userAgent: defaultUserAgent,
};
await testNavigator();
@@ -460,12 +450,8 @@ add_task(async function setupResistFingerprinting() {
let spoofedGeckoTrail = SPOOFED_UA_GECKO_TRAIL[AppConstants.platform];
let spoofedUserAgentNavigator = `Mozilla/5.0 (${
SPOOFED_UA_NAVIGATOR_OS[AppConstants.platform]
}; rv:${appVersion}.0) Gecko/${spoofedGeckoTrail} Firefox/${appVersion}.0`;
let spoofedUserAgentHeader = `Mozilla/5.0 (${
SPOOFED_UA_HTTPHEADER_OS[AppConstants.platform]
let spoofedUserAgent = `Mozilla/5.0 (${
SPOOFED_UA_OS[AppConstants.platform]
}; rv:${appVersion}.0) Gecko/${spoofedGeckoTrail} Firefox/${appVersion}.0`;
expectedResults = {
@@ -476,8 +462,7 @@ add_task(async function setupResistFingerprinting() {
oscpu: SPOOFED_OSCPU[AppConstants.platform],
platform: DEFAULT_PLATFORM[AppConstants.platform],
pluginsLength: 5,
userAgentNavigator: spoofedUserAgentNavigator,
userAgentHeader: spoofedUserAgentHeader,
userAgent: spoofedUserAgent,
};
await testNavigator();

View File

@@ -96,20 +96,13 @@ const DEFAULT_UA_OS = {
other: "X11; Linux x86_64",
};
const SPOOFED_UA_NAVIGATOR_OS = {
const SPOOFED_UA_OS = {
linux: "X11; Linux x86_64",
win: "Windows NT 10.0; Win64; x64",
macosx: "Macintosh; Intel Mac OS X 10.15",
android: "Android 10; Mobile",
other: "X11; Linux x86_64",
};
const SPOOFED_UA_HTTPHEADER_OS = {
linux: "Windows NT 10.0; Win64; x64",
win: "Windows NT 10.0; Win64; x64",
macosx: "Windows NT 10.0; Win64; x64",
android: "Android 10; Mobile",
other: "Windows NT 10.0; Win64; x64",
};
const SPOOFED_HW_CONCURRENCY = 2;
const CONST_APPCODENAME = "Mozilla";
@@ -160,12 +153,12 @@ async function testNavigator(result, expectedResults, extraData) {
);
is(
result.userAgent,
expectedResults.userAgentNavigator,
expectedResults.userAgent,
`Checking ${testDesc} navigator.userAgent.`
);
is(
result.userAgentHTTPHeader,
expectedResults.userAgentHTTPHeader,
expectedResults.userAgent,
`Checking ${testDesc} userAgentHTTPHeader.`
);
is(
@@ -242,7 +235,7 @@ async function testNavigator(result, expectedResults, extraData) {
);
is(
result.worker_userAgent,
expectedResults.userAgentNavigator,
expectedResults.userAgent,
`Checking ${testDesc} worker navigator.userAgent.`
);
is(
@@ -269,8 +262,7 @@ async function testNavigator(result, expectedResults, extraData) {
}
let defaultUserAgent;
let spoofedUserAgentNavigator;
let spoofedUserAgentHeader;
let spoofedUserAgent;
let allNotSpoofed;
let allSpoofed;
@@ -282,14 +274,8 @@ add_setup(async () => {
DEFAULT_UA_GECKO_TRAIL[AppConstants.platform]
} Firefox/${appVersion}.0`;
spoofedUserAgentNavigator = `Mozilla/5.0 (${
SPOOFED_UA_NAVIGATOR_OS[AppConstants.platform]
}; rv:${appVersion}.0) Gecko/${
SPOOFED_UA_GECKO_TRAIL[AppConstants.platform]
} Firefox/${appVersion}.0`;
spoofedUserAgentHeader = `Mozilla/5.0 (${
SPOOFED_UA_HTTPHEADER_OS[AppConstants.platform]
spoofedUserAgent = `Mozilla/5.0 (${
SPOOFED_UA_OS[AppConstants.platform]
}; rv:${appVersion}.0) Gecko/${
SPOOFED_UA_GECKO_TRAIL[AppConstants.platform]
} Firefox/${appVersion}.0`;
@@ -305,8 +291,7 @@ add_setup(async () => {
oscpu: DEFAULT_OSCPU[AppConstants.platform],
platform: DEFAULT_PLATFORM[AppConstants.platform],
pluginsLength: 5,
userAgentNavigator: defaultUserAgent,
userAgentHTTPHeader: defaultUserAgent,
userAgent: defaultUserAgent,
framer_crossOrigin_userAgentHTTPHeader: defaultUserAgent,
framee_crossOrigin_userAgentHTTPHeader: defaultUserAgent,
};
@@ -317,10 +302,9 @@ add_setup(async () => {
oscpu: SPOOFED_OSCPU[AppConstants.platform],
platform: DEFAULT_PLATFORM[AppConstants.platform],
pluginsLength: 5,
userAgentNavigator: spoofedUserAgentNavigator,
userAgentHTTPHeader: spoofedUserAgentHeader,
framer_crossOrigin_userAgentHTTPHeader: spoofedUserAgentHeader,
framee_crossOrigin_userAgentHTTPHeader: spoofedUserAgentHeader,
userAgent: spoofedUserAgent,
framer_crossOrigin_userAgentHTTPHeader: spoofedUserAgent,
framee_crossOrigin_userAgentHTTPHeader: spoofedUserAgent,
};
});
@@ -359,8 +343,7 @@ add_task(async () => {
add_task(async () => {
expectedResults = structuredClone(allSpoofed);
expectedResults.framer_crossOrigin_userAgentHTTPHeader = defaultUserAgent;
expectedResults.framee_crossOrigin_userAgentHTTPHeader =
spoofedUserAgentHeader;
expectedResults.framee_crossOrigin_userAgentHTTPHeader = spoofedUserAgent;
await testC(uri, testNavigator, expectedResults);
});
@@ -368,8 +351,7 @@ add_task(async () => {
add_task(async () => {
expectedResults = structuredClone(allSpoofed);
expectedResults.framer_crossOrigin_userAgentHTTPHeader = defaultUserAgent;
expectedResults.framee_crossOrigin_userAgentHTTPHeader =
spoofedUserAgentHeader;
expectedResults.framee_crossOrigin_userAgentHTTPHeader = spoofedUserAgent;
await testD(uri, testNavigator, expectedResults);
});

View File

@@ -2103,7 +2103,7 @@ nsresult Navigator::GetUserAgent(nsPIDOMWindowInner* aWindow,
// specific OS version, etc.
if (shouldResistFingerprinting) {
nsAutoCString spoofedUA;
nsRFPService::GetSpoofedUserAgent(spoofedUA, false);
nsRFPService::GetSpoofedUserAgent(spoofedUA);
CopyASCIItoUTF16(spoofedUA, aUserAgent);
return NS_OK;
}

View File

@@ -442,7 +442,7 @@ nsresult nsHttpHandler::Init() {
mMisc.AssignLiteral("rv:" MOZILLA_UAVERSION);
// Generate the spoofed User Agent for fingerprinting resistance.
nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent, true);
nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent);
mSessionStartTime = NowInSeconds();
mHandlerActive = true;

View File

@@ -975,8 +975,7 @@ uint32_t nsRFPService::GetSpoofedPresentedFrames(double aTime, uint32_t aWidth,
// User-Agent/Version Stuff
/* static */
void nsRFPService::GetSpoofedUserAgent(nsACString& userAgent,
bool isForHTTPHeader) {
void nsRFPService::GetSpoofedUserAgent(nsACString& userAgent) {
// This function generates the spoofed value of User Agent.
// We spoof the values of the platform and Firefox version, which could be
// used as fingerprinting sources to identify individuals.
@@ -986,30 +985,19 @@ void nsRFPService::GetSpoofedUserAgent(nsACString& userAgent,
// These magic numbers are the lengths of the UA string literals below.
// Assume three-digit Firefox version numbers so we have room to grow.
size_t preallocatedLength = 13 +
(isForHTTPHeader ? std::size(SPOOFED_HTTP_UA_OS)
: std::size(SPOOFED_UA_OS)) -
1 + 5 + 3 + 10 +
size_t preallocatedLength = 13 + std::size(SPOOFED_UA_OS) - 1 + 5 + 3 + 10 +
std::size(LEGACY_UA_GECKO_TRAIL) - 1 + 9 + 3 + 2;
userAgent.SetCapacity(preallocatedLength);
// "Mozilla/5.0 (%s; rv:%d.0) Gecko/%d Firefox/%d.0"
userAgent.AssignLiteral("Mozilla/5.0 (");
if (isForHTTPHeader) {
userAgent.AppendLiteral(SPOOFED_HTTP_UA_OS);
} else {
userAgent.AppendLiteral(SPOOFED_UA_OS);
}
userAgent.AppendLiteral(SPOOFED_UA_OS);
userAgent.AppendLiteral("; rv:" MOZILLA_UAVERSION ") Gecko/");
#if defined(ANDROID)
userAgent.AppendLiteral(MOZILLA_UAVERSION);
#else
userAgent.AppendLiteral(LEGACY_UA_GECKO_TRAIL);
#endif
userAgent.AppendLiteral(" Firefox/" MOZILLA_UAVERSION);
MOZ_ASSERT(userAgent.Length() <= preallocatedLength);

View File

@@ -61,14 +61,6 @@
#define SPOOFED_POINTER_INTERFACE MouseEvent_Binding::MOZ_SOURCE_MOUSE
// For the HTTP User-Agent header, we use a simpler set of spoofed values
// that do not reveal the specific desktop platform.
#if defined(MOZ_WIDGET_ANDROID)
# define SPOOFED_HTTP_UA_OS "Android 10; Mobile"
#else
# define SPOOFED_HTTP_UA_OS "Windows NT 10.0; Win64; x64"
#endif
struct JSContext;
class nsIChannel;
@@ -278,7 +270,7 @@ class nsRFPService final : public nsIObserver, public nsIRFPService {
// --------------------------------------------------------------------------
// This method generates the spoofed value of User Agent.
static void GetSpoofedUserAgent(nsACString& userAgent, bool isForHTTPHeader);
static void GetSpoofedUserAgent(nsACString& userAgent);
// --------------------------------------------------------------------------