Bug 587523 - strict-origin-when-cross-origin referer policy in pbmode draft
authorLuke Crouch <lcrouch@mozilla.com>
Wed, 10 Jan 2018 16:33:52 -0600
changeset 721172 4a812da83f4328f8d6ea186a8c52e393f3043635
parent 717183 ca379fcca95b1f4a3744242ea8647004b99b3507
child 721173 30d4f604fc4c5620188596496a58fe87c980edf1
push id95757
push userbmo:lcrouch@mozilla.com
push dateTue, 16 Jan 2018 21:27:21 +0000
bugs587523
milestone59.0a1
Bug 587523 - strict-origin-when-cross-origin referer policy in pbmode Adds new network.http.referer.defaultPolicy.pbmode pref which defaults to 2. When setting referrer from default policy, checks mLoadInfo OriginAttributes for mPrivateBrowsingId > 0 to detect PBM. MozReview-Commit-ID: 7SfNk0dO1rW
modules/libpref/init/all.js
netwerk/base/nsNetUtil.cpp
netwerk/base/nsNetUtil.h
netwerk/protocol/http/HttpBaseChannel.cpp
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1670,20 +1670,24 @@ pref("network.http.request.max-start-del
 pref("network.http.request.max-attempts", 10);
 
 // Headers
 pref("network.http.accept.default", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
 
 // Prefs allowing granular control of referers
 // 0=don't send any, 1=send only on clicks, 2=send on image requests as well
 pref("network.http.sendRefererHeader",      2);
-// Set the default Referrer Policy to be used unless overriden by the site
+// Set the default Referrer Policy; to be used unless overriden by the site
 // 0=no-referrer, 1=same-origin, 2=strict-origin-when-cross-origin,
 // 3=no-referrer-when-downgrade
 pref("network.http.referer.userControlPolicy", 3);
+// Set the Private Browsing Defaul Referrer Policy;
+// to be used unless overriden by the site;
+// values are identical to defaultPolicy above
+pref("network.http.referer.defaultPolicy.pbmode", 2);
 // false=real referer, true=spoof referer (use target URI as referer)
 pref("network.http.referer.spoofSource", false);
 // false=allow onion referer, true=hide onion referer (use empty referer)
 pref("network.http.referer.hideOnionSource", false);
 // 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port
 pref("network.http.referer.trimmingPolicy", 0);
 // 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port
 pref("network.http.referer.XOriginTrimmingPolicy", 0);
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -79,18 +79,20 @@
 #include "nsICertOverrideService.h"
 
 #include <limits>
 
 using namespace mozilla;
 using namespace mozilla::net;
 
 #define DEFAULT_USER_CONTROL_RP 3
+#define DEFAULT_USER_CONTROL_PRIVATE_RP 2
 
 static uint32_t sUserControlRp = DEFAULT_USER_CONTROL_RP;
+static uint32_t sUserControlPrivateRp = DEFAULT_USER_CONTROL_PRIVATE_RP;
 
 already_AddRefed<nsIIOService>
 do_GetIOService(nsresult *error /* = 0 */)
 {
     nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
     if (error)
         *error = io ? NS_OK : NS_ERROR_FAILURE;
     return io.forget();
@@ -2994,28 +2996,38 @@ NS_CompareLoadInfoAndLoadContext(nsIChan
              originAttrsLoadContext.mPrivateBrowsingId,
              "The value of mPrivateBrowsingId in the loadContext and in the "
              "loadInfo are not the same!");
 
   return NS_OK;
 }
 
 uint32_t
-NS_GetDefaultReferrerPolicy()
+NS_GetDefaultReferrerPolicy(bool privateBrowsing)
 {
   static bool preferencesInitialized = false;
 
   if (!preferencesInitialized) {
     mozilla::Preferences::AddUintVarCache(&sUserControlRp,
                                           "network.http.referer.userControlPolicy",
                                           DEFAULT_USER_CONTROL_RP);
+    mozilla::Preferences::AddUintVarCache(&sUserControlPrivateRp,
+                                          "network.http.referer.defaultPolicy.pbmode",
+                                          DEFAULT_USER_CONTROL_PRIVATE_RP);
     preferencesInitialized = true;
   }
 
-  switch (sUserControlRp) {
+  uint32_t defaultToUse;
+  if (privateBrowsing) {
+      defaultToUse = sUserControlPrivateRp;
+  } else {
+      defaultToUse = sUserControlRp;
+  }
+
+  switch (defaultToUse) {
     case 0:
       return nsIHttpChannel::REFERRER_POLICY_NO_REFERRER;
     case 1:
       return nsIHttpChannel::REFERRER_POLICY_SAME_ORIGIN;
     case 2:
       return nsIHttpChannel::REFERRER_POLICY_STRICT_ORIGIN_WHEN_XORIGIN;
   }
 
--- a/netwerk/base/nsNetUtil.h
+++ b/netwerk/base/nsNetUtil.h
@@ -930,19 +930,21 @@ nsresult NS_ShouldSecureUpgrade(nsIURI* 
  * Returns an https URI for channels that need to go through secure upgrades.
  */
 nsresult NS_GetSecureUpgradedURI(nsIURI* aURI, nsIURI** aUpgradedURI);
 
 nsresult NS_CompareLoadInfoAndLoadContext(nsIChannel *aChannel);
 
 /**
  * Return default referrer policy which is controlled by user
- * pref network.http.referer.userControlPolicy
+ * prefs:
+ * network.http.referer.userControlPolicy for regular mode
+ * network.http.referer.userControlPrivatePolicy for private mode
  */
-uint32_t NS_GetDefaultReferrerPolicy();
+uint32_t NS_GetDefaultReferrerPolicy(bool privateBrowsing = false);
 
 namespace mozilla {
 namespace net {
 
 const static uint64_t kJS_MAX_SAFE_UINTEGER = +9007199254740991ULL;
 const static  int64_t kJS_MIN_SAFE_INTEGER  = -9007199254740991LL;
 const static  int64_t kJS_MAX_SAFE_INTEGER  = +9007199254740991LL;
 
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1619,17 +1619,21 @@ HttpBaseChannel::SetReferrerWithPolicy(n
   // clear existing referrer, if any
   mReferrer = nullptr;
   nsresult rv = mRequestHead.ClearHeader(nsHttp::Referer);
   if(NS_FAILED(rv)) {
     return rv;
   }
 
   if (mReferrerPolicy == REFERRER_POLICY_UNSET) {
-    mReferrerPolicy = NS_GetDefaultReferrerPolicy();
+    if (mLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0) {
+      mReferrerPolicy = NS_GetDefaultReferrerPolicy(true);
+    } else {
+      mReferrerPolicy = NS_GetDefaultReferrerPolicy();
+    }
   }
 
   if (!referrer) {
     return NS_OK;
   }
 
   // Don't send referrer at all when the meta referrer setting is "no-referrer"
   if (mReferrerPolicy == REFERRER_POLICY_NO_REFERRER) {