Commit 511d1d80 authored by Kathleen Brade's avatar Kathleen Brade Committed by Georg Koppen
Browse files

Bug 26146: Spoof HTTP User-Agent header for desktop platforms

In Tor Browser 8.0, the OS was revealed in both the HTTP User-Agent
header and to JavaScript code via navigator.userAgent. To avoid
leaking the OS inside each HTTP request (which many web servers
log), always use the Windows 7 OS value in the desktop User-Agent
header. We continue to allow access to the actual OS via JavaScript,
since doing so improves compatibility with web applications such
as GitHub and Google Docs.
parent 15ee4460
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -122,7 +122,6 @@ pref("general.appname.override", "Netscape");
pref("general.appversion.override", "5.0 (Windows)");
pref("general.oscpu.override", "Windows NT 6.1");
pref("general.platform.override", "Win32");
pref("general.useragent.override", "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0");
pref("general.productSub.override", "20100101");
pref("general.buildID.override", "20100101");
pref("browser.startup.homepage_override.buildID", "20100101");
+13 −0
Original line number Diff line number Diff line
@@ -1772,6 +1772,19 @@ Navigator::GetUserAgent(nsPIDOMWindowInner* aWindow,
    }
  }

  // When the caller is content and 'privacy.resistFingerprinting' is true,
  // return a spoofed userAgent which reveals the platform but not the
  // specific OS version, etc.
  if (!aIsCallerChrome && nsContentUtils::ShouldResistFingerprinting()) {
    nsAutoCString spoofedUA;
    nsresult rv = nsRFPService::GetSpoofedUserAgent(spoofedUA, false);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
    CopyASCIItoUTF16(spoofedUA, aUserAgent);
    return NS_OK;
  }

  nsresult rv;
  nsCOMPtr<nsIHttpProtocolHandler>
    service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
+1 −1
Original line number Diff line number Diff line
@@ -491,7 +491,7 @@ nsHttpHandler::Init()
    }

    // Generating the spoofed User Agent for fingerprinting resistance.
    rv = nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent);
    rv = nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent, true);
    if (NS_FAILED(rv)) {
      // Empty mSpoofedUserAgent to make sure the unsuccessful spoofed UA string
      // will not be used anywhere.
+3 −2
Original line number Diff line number Diff line
@@ -666,7 +666,7 @@ nsRFPService::GetSpoofedPresentedFrames(double aTime, uint32_t aWidth, uint32_t

/* static */
nsresult
nsRFPService::GetSpoofedUserAgent(nsACString &userAgent)
nsRFPService::GetSpoofedUserAgent(nsACString &userAgent, bool isForHTTPHeader)
{
  // This function generates the spoofed value of User Agent.
  // We spoof the values of the platform and Firefox version, which could be
@@ -703,9 +703,10 @@ nsRFPService::GetSpoofedUserAgent(nsACString &userAgent)
  // Except we used 60 as an ESR instead of 59.
  // We infer the last and closest ESR version based on this rule.
  uint32_t spoofedVersion = firefoxVersion - ((firefoxVersion - 4) % 7);
  const char *spoofedOS = isForHTTPHeader ? SPOOFED_HTTP_UA_OS : SPOOFED_UA_OS;
  userAgent.Assign(nsPrintfCString(
    "Mozilla/5.0 (%s; rv:%d.0) Gecko/%s Firefox/%d.0",
    SPOOFED_UA_OS, spoofedVersion, LEGACY_BUILD_ID, spoofedVersion));
    spoofedOS, spoofedVersion, LEGACY_BUILD_ID, spoofedVersion));

  return rv;
}
+9 −1
Original line number Diff line number Diff line
@@ -48,6 +48,14 @@
#define SPOOFED_APPNAME    "Netscape"
#define LEGACY_BUILD_ID    "20100101"

// 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 6.0; Mobile"
#else
#define SPOOFED_HTTP_UA_OS      "Windows NT 6.1"
#endif

// Forward declare LRUCache, defined in nsRFPService.cpp
class LRUCache;

@@ -212,7 +220,7 @@ public:
  static uint32_t GetSpoofedPresentedFrames(double aTime, uint32_t aWidth, uint32_t aHeight);

  // This method generates the spoofed value of User Agent.
  static nsresult GetSpoofedUserAgent(nsACString &userAgent);
  static nsresult GetSpoofedUserAgent(nsACString &userAgent, bool isForHTTPHeader);

  /**
   * This method for getting spoofed modifier states for the given keyboard event.