[tor-commits] [tor-browser/tor-browser-60.2.0esr-8.0-1] Bug 26146: Spoof HTTP User-Agent header for desktop platforms

gk at torproject.org gk at torproject.org
Fri Sep 14 15:20:50 UTC 2018


commit 62d76b2381c1df0b893336f496ae4ffe161d592f
Author: Kathy Brade <brade at pearlcrescent.com>
Date:   Fri Sep 14 10:02:17 2018 -0400

    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.
---
 browser/app/profile/000-tor-browser.js                   |  1 -
 dom/base/Navigator.cpp                                   | 13 +++++++++++++
 netwerk/protocol/http/nsHttpHandler.cpp                  |  2 +-
 toolkit/components/resistfingerprinting/nsRFPService.cpp |  5 +++--
 toolkit/components/resistfingerprinting/nsRFPService.h   | 10 +++++++++-
 5 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js
index d9e609a71eb8..7b602c13e0d5 100644
--- a/browser/app/profile/000-tor-browser.js
+++ b/browser/app/profile/000-tor-browser.js
@@ -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");
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
index c2ec1f7081a3..33563ad65ccb 100644
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -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));
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
index f7f449868711..18f942c216fb 100644
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -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.
diff --git a/toolkit/components/resistfingerprinting/nsRFPService.cpp b/toolkit/components/resistfingerprinting/nsRFPService.cpp
index f560ce27f228..595e6556a27e 100644
--- a/toolkit/components/resistfingerprinting/nsRFPService.cpp
+++ b/toolkit/components/resistfingerprinting/nsRFPService.cpp
@@ -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;
 }
diff --git a/toolkit/components/resistfingerprinting/nsRFPService.h b/toolkit/components/resistfingerprinting/nsRFPService.h
index 9708d362496f..da79da8de948 100644
--- a/toolkit/components/resistfingerprinting/nsRFPService.h
+++ b/toolkit/components/resistfingerprinting/nsRFPService.h
@@ -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.



More information about the tor-commits mailing list