Bug 1532402 - Part 3: Pass a principal pointer nsContentUtils::ShouldResistFingerprinting() in the user-agent spoofing code for the rest of the Navigator properties; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 05 Mar 2019 23:13:22 +0000
changeset 520386 53f514ed49897c5df87058b6413ac5a696af4662
parent 520385 ae40b04ca98b76683278c04f5720911c41e2d116
child 520387 152b9d59cb2903aff4b14c88836eaf051181e1fb
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1532402
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1532402 - Part 3: Pass a principal pointer nsContentUtils::ShouldResistFingerprinting() in the user-agent spoofing code for the rest of the Navigator properties; r=baku Depends on D21991 Differential Revision: https://phabricator.services.mozilla.com/D21992
dom/base/Navigator.cpp
dom/base/Navigator.h
dom/workers/RuntimeService.cpp
dom/workers/WorkerNavigator.cpp
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -238,18 +238,20 @@ void Navigator::GetUserAgent(nsAString& 
 
       if (!customUserAgent.IsEmpty()) {
         aUserAgent = customUserAgent;
         return;
       }
     }
   }
 
-  nsresult rv =
-      GetUserAgent(window, aCallerType == CallerType::System, aUserAgent);
+  nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
+
+  nsresult rv = GetUserAgent(window, doc ? doc->NodePrincipal() : nullptr,
+                             aCallerType == CallerType::System, aUserAgent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
   }
 }
 
 void Navigator::GetAppCodeName(nsAString& aAppCodeName, ErrorResult& aRv) {
   nsresult rv;
 
@@ -267,26 +269,30 @@ void Navigator::GetAppCodeName(nsAString
     return;
   }
 
   CopyASCIItoUTF16(appName, aAppCodeName);
 }
 
 void Navigator::GetAppVersion(nsAString& aAppVersion, CallerType aCallerType,
                               ErrorResult& aRv) const {
+  nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
+
   nsresult rv = GetAppVersion(
-      aAppVersion,
+      aAppVersion, doc ? doc->NodePrincipal() : nullptr,
       /* aUsePrefOverriddenValue = */ aCallerType != CallerType::System);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
   }
 }
 
 void Navigator::GetAppName(nsAString& aAppName, CallerType aCallerType) const {
-  AppName(aAppName,
+  nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
+
+  AppName(aAppName, doc ? doc->NodePrincipal() : nullptr,
           /* aUsePrefOverriddenValue = */ aCallerType != CallerType::System);
 }
 
 /**
  * Returns the value of Accept-Languages (HTTP header) as a nsTArray of
  * languages. The value is set in the preference by the user ("Content
  * Languages").
  *
@@ -363,18 +369,20 @@ void Navigator::GetLanguages(nsTArray<ns
   // The returned value is cached by the binding code. The window listen to the
   // accept languages change and will clear the cache when needed. It has to
   // take care of dispatching the DOM event already and the invalidation and the
   // event has to be timed correctly.
 }
 
 void Navigator::GetPlatform(nsAString& aPlatform, CallerType aCallerType,
                             ErrorResult& aRv) const {
+  nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
+
   nsresult rv = GetPlatform(
-      aPlatform,
+      aPlatform, doc ? doc->NodePrincipal() : nullptr,
       /* aUsePrefOverriddenValue = */ aCallerType != CallerType::System);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
   }
 }
 
 void Navigator::GetOscpu(nsAString& aOSCPU, CallerType aCallerType,
                          ErrorResult& aRv) const {
@@ -1022,18 +1030,17 @@ BeaconStreamListener::OnStartRequest(nsI
   // release the loadgroup first
   mLoadGroup = nullptr;
 
   aRequest->Cancel(NS_ERROR_NET_INTERRUPT);
   return NS_BINDING_ABORTED;
 }
 
 NS_IMETHODIMP
-BeaconStreamListener::OnStopRequest(nsIRequest* aRequest,
-                                    nsresult aStatus) {
+BeaconStreamListener::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BeaconStreamListener::OnDataAvailable(nsIRequest* aRequest,
                                       nsIInputStream* inStr,
                                       uint64_t sourceOffset, uint32_t count) {
   MOZ_ASSERT(false);
@@ -1519,23 +1526,24 @@ bool Navigator::HasUserMediaSupport(JSCo
 /* static */
 already_AddRefed<nsPIDOMWindowInner> Navigator::GetWindowFromGlobal(
     JSObject* aGlobal) {
   nsCOMPtr<nsPIDOMWindowInner> win = xpc::WindowOrNull(aGlobal);
   return win.forget();
 }
 
 nsresult Navigator::GetPlatform(nsAString& aPlatform,
+                                nsIPrincipal* aCallerPrincipal,
                                 bool aUsePrefOverriddenValue) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aUsePrefOverriddenValue) {
     // If fingerprinting resistance is on, we will spoof this value. See
     // nsRFPService.h for details about spoofed values.
-    if (nsContentUtils::ShouldResistFingerprinting()) {
+    if (nsContentUtils::ShouldResistFingerprinting(aCallerPrincipal)) {
       aPlatform.AssignLiteral(SPOOFED_PLATFORM);
       return NS_OK;
     }
     nsAutoString override;
     nsresult rv =
         mozilla::Preferences::GetString("general.platform.override", override);
 
     if (NS_SUCCEEDED(rv)) {
@@ -1569,23 +1577,24 @@ nsresult Navigator::GetPlatform(nsAStrin
   CopyASCIItoUTF16(plat, aPlatform);
 #endif
 
   return rv;
 }
 
 /* static */
 nsresult Navigator::GetAppVersion(nsAString& aAppVersion,
+                                  nsIPrincipal* aCallerPrincipal,
                                   bool aUsePrefOverriddenValue) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aUsePrefOverriddenValue) {
     // If fingerprinting resistance is on, we will spoof this value. See
     // nsRFPService.h for details about spoofed values.
-    if (nsContentUtils::ShouldResistFingerprinting()) {
+    if (nsContentUtils::ShouldResistFingerprinting(aCallerPrincipal)) {
       aAppVersion.AssignLiteral(SPOOFED_APPVERSION);
       return NS_OK;
     }
     nsAutoString override;
     nsresult rv = mozilla::Preferences::GetString("general.appversion.override",
                                                   override);
 
     if (NS_SUCCEEDED(rv)) {
@@ -1612,23 +1621,24 @@ nsresult Navigator::GetAppVersion(nsAStr
 
   AppendASCIItoUTF16(str, aAppVersion);
   aAppVersion.Append(char16_t(')'));
 
   return rv;
 }
 
 /* static */
-void Navigator::AppName(nsAString& aAppName, bool aUsePrefOverriddenValue) {
+void Navigator::AppName(nsAString& aAppName, nsIPrincipal* aCallerPrincipal,
+                        bool aUsePrefOverriddenValue) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aUsePrefOverriddenValue) {
     // If fingerprinting resistance is on, we will spoof this value. See
     // nsRFPService.h for details about spoofed values.
-    if (nsContentUtils::ShouldResistFingerprinting()) {
+    if (nsContentUtils::ShouldResistFingerprinting(aCallerPrincipal)) {
       aAppName.AssignLiteral(SPOOFED_APPNAME);
       return;
     }
 
     nsAutoString override;
     nsresult rv =
         mozilla::Preferences::GetString("general.appname.override", override);
 
@@ -1641,36 +1651,39 @@ void Navigator::AppName(nsAString& aAppN
   aAppName.AssignLiteral("Netscape");
 }
 
 void Navigator::ClearUserAgentCache() {
   Navigator_Binding::ClearCachedUserAgentValue(this);
 }
 
 nsresult Navigator::GetUserAgent(nsPIDOMWindowInner* aWindow,
+                                 nsIPrincipal* aCallerPrincipal,
                                  bool aIsCallerChrome, nsAString& aUserAgent) {
   MOZ_ASSERT(NS_IsMainThread());
 
   // We will skip the override and pass to httpHandler to get spoofed userAgent
   // when 'privacy.resistFingerprinting' is true.
-  if (!aIsCallerChrome && !nsContentUtils::ShouldResistFingerprinting()) {
+  if (!aIsCallerChrome &&
+      !nsContentUtils::ShouldResistFingerprinting(aCallerPrincipal)) {
     nsAutoString override;
     nsresult rv =
         mozilla::Preferences::GetString("general.useragent.override", override);
 
     if (NS_SUCCEEDED(rv)) {
       aUserAgent = override;
       return NS_OK;
     }
   }
 
   // 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()) {
+  if (!aIsCallerChrome &&
+      nsContentUtils::ShouldResistFingerprinting(aCallerPrincipal)) {
     nsAutoCString spoofedUA;
     nsRFPService::GetSpoofedUserAgent(spoofedUA, false);
     CopyASCIItoUTF16(spoofedUA, aUserAgent);
     return NS_OK;
   }
 
   nsresult rv;
   nsCOMPtr<nsIHttpProtocolHandler> service(
@@ -1686,17 +1699,18 @@ nsresult Navigator::GetUserAgent(nsPIDOM
   }
 
   CopyASCIItoUTF16(ua, aUserAgent);
 
   // When the caller is content, we will always return spoofed userAgent and
   // ignore the User-Agent header from the document channel when
   // 'privacy.resistFingerprinting' is true.
   if (!aWindow ||
-      (nsContentUtils::ShouldResistFingerprinting() && !aIsCallerChrome)) {
+      (nsContentUtils::ShouldResistFingerprinting(aCallerPrincipal) &&
+       !aIsCallerChrome)) {
     return NS_OK;
   }
 
   // Copy the User-Agent header from the document channel which has already been
   // subject to UA overrides.
   nsCOMPtr<Document> doc = aWindow->GetExtantDoc();
   if (!doc) {
     return NS_OK;
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -121,25 +121,29 @@ class Navigator final : public nsISuppor
                               const nsAString& aTitle, ErrorResult& aRv);
   nsMimeTypeArray* GetMimeTypes(ErrorResult& aRv);
   nsPluginArray* GetPlugins(ErrorResult& aRv);
   Permissions* GetPermissions(ErrorResult& aRv);
   void GetDoNotTrack(nsAString& aResult);
   Geolocation* GetGeolocation(ErrorResult& aRv);
   Promise* GetBattery(ErrorResult& aRv);
 
-  static void AppName(nsAString& aAppName, bool aUsePrefOverriddenValue);
+  static void AppName(nsAString& aAppName, nsIPrincipal* aCallerPrincipal,
+                      bool aUsePrefOverriddenValue);
 
   static nsresult GetPlatform(nsAString& aPlatform,
+                              nsIPrincipal* aCallerPrincipal,
                               bool aUsePrefOverriddenValue);
 
   static nsresult GetAppVersion(nsAString& aAppVersion,
+                                nsIPrincipal* aCallerPrincipal,
                                 bool aUsePrefOverriddenValue);
 
   static nsresult GetUserAgent(nsPIDOMWindowInner* aWindow,
+                               nsIPrincipal* aCallerPrincipal,
                                bool aIsCallerChrome, nsAString& aUserAgent);
 
   // Clears the user agent cache by calling:
   // Navigator_Binding::ClearCachedUserAgentValue(this);
   void ClearUserAgentCache();
 
   bool Vibrate(uint32_t aDuration);
   bool Vibrate(const nsTArray<uint32_t>& aDuration);
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -1251,23 +1251,24 @@ bool RuntimeService::RegisterWorker(Work
   if (parent) {
     if (!parent->AddChildWorker(aWorkerPrivate)) {
       UnregisterWorker(aWorkerPrivate);
       return false;
     }
   } else {
     if (!mNavigatorPropertiesLoaded) {
       Navigator::AppName(mNavigatorProperties.mAppName,
+                         aWorkerPrivate->GetPrincipal(),
                          false /* aUsePrefOverriddenValue */);
-      if (NS_FAILED(
-              Navigator::GetAppVersion(mNavigatorProperties.mAppVersion,
-                                       false /* aUsePrefOverriddenValue */)) ||
-          NS_FAILED(
-              Navigator::GetPlatform(mNavigatorProperties.mPlatform,
-                                     false /* aUsePrefOverriddenValue */))) {
+      if (NS_FAILED(Navigator::GetAppVersion(
+              mNavigatorProperties.mAppVersion, aWorkerPrivate->GetPrincipal(),
+              false /* aUsePrefOverriddenValue */)) ||
+          NS_FAILED(Navigator::GetPlatform(
+              mNavigatorProperties.mPlatform, aWorkerPrivate->GetPrincipal(),
+              false /* aUsePrefOverriddenValue */))) {
         UnregisterWorker(aWorkerPrivate);
         return false;
       }
 
       // The navigator overridden properties should have already been read.
 
       Navigator::GetAcceptLanguages(mNavigatorProperties.mLanguages);
       mNavigatorPropertiesLoaded = true;
--- a/dom/workers/WorkerNavigator.cpp
+++ b/dom/workers/WorkerNavigator.cpp
@@ -136,17 +136,18 @@ class GetUserAgentRunnable final : publi
   }
 
   virtual bool MainThreadRun() override {
     AssertIsOnMainThread();
 
     nsCOMPtr<nsPIDOMWindowInner> window = mWorkerPrivate->GetWindow();
 
     bool isCallerChrome = mWorkerPrivate->UsesSystemPrincipal();
-    nsresult rv = dom::Navigator::GetUserAgent(window, isCallerChrome, mUA);
+    nsresult rv = dom::Navigator::GetUserAgent(
+        window, mWorkerPrivate->GetPrincipal(), isCallerChrome, mUA);
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to retrieve user-agent from the worker thread.");
     }
 
     return true;
   }
 };