Bug 1320402 - Part 2 : Replace NECKO_SAFEBROWSING_APP_ID to a well-known first-party domain value. r?ehsan, gcp draft
authorDimiL <dlee@mozilla.com>
Wed, 21 Dec 2016 10:03:57 +0800
changeset 451838 a1494a0cf517a91e993234c82f577921c07e349d
parent 451837 9f5a38b7cf7972ca0759b4fa3a27b4751616764a
child 540141 39fa45020af72fe49e6455e9506abf3c3ca4640f
push id39306
push userdlee@mozilla.com
push dateWed, 21 Dec 2016 02:04:38 +0000
reviewersehsan, gcp
bugs1320402
milestone53.0a1
Bug 1320402 - Part 2 : Replace NECKO_SAFEBROWSING_APP_ID to a well-known first-party domain value. r?ehsan, gcp MozReview-Commit-ID: 4yBaPuJDwZZ
caps/nsIScriptSecurityManager.idl
docshell/base/LoadContext.h
netwerk/base/nsNetUtil.h
netwerk/test/unit/test_cookiejars_safebrowsing.js
toolkit/components/downloads/ApplicationReputation.cpp
toolkit/components/url-classifier/content/xml-fetcher.js
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
--- a/caps/nsIScriptSecurityManager.idl
+++ b/caps/nsIScriptSecurityManager.idl
@@ -251,17 +251,16 @@ interface nsIScriptSecurityManager : nsI
       bool isSystem = false;
       IsSystemPrincipal(aPrincipal, &isSystem);
       return isSystem;
     }
 %}
 
     const unsigned long NO_APP_ID = 0;
     const unsigned long UNKNOWN_APP_ID = 4294967295; // UINT32_MAX
-    const unsigned long SAFEBROWSING_APP_ID = 4294967294; // UINT32_MAX - 1
 
     const unsigned long DEFAULT_USER_CONTEXT_ID = 0;
 
     /**
      * Per-domain controls to enable and disable script. This system is designed
      * to be used by at most one consumer, and enforces this with its semantics.
      *
      * Initially, domainPolicyActive is false. When activateDomainPolicy() is
--- a/docshell/base/LoadContext.h
+++ b/docshell/base/LoadContext.h
@@ -20,19 +20,16 @@ namespace mozilla {
 /**
  * Class that provides nsILoadContext info in Parent process.  Typically copied
  * from Child via SerializedLoadContext.
  *
  * Note: this is not the "normal" or "original" nsILoadContext.  That is
  * typically provided by nsDocShell.  This is only used when the original
  * docshell is in a different process and we need to copy certain values from
  * it.
- *
- * Note: we also generate a new nsILoadContext using LoadContext(uint32_t aAppId)
- * to separate the safebrowsing cookie.
  */
 
 class LoadContext final
   : public nsILoadContext
   , public nsIInterfaceRequestor
 {
 public:
   NS_DECL_ISUPPORTS
--- a/netwerk/base/nsNetUtil.h
+++ b/netwerk/base/nsNetUtil.h
@@ -667,18 +667,22 @@ bool NS_GetOriginAttributes(nsIChannel *
  * URLs that it was redirected through.
  */
 bool NS_HasBeenCrossOrigin(nsIChannel* aChannel, bool aReport = false);
 
 // Constants duplicated from nsIScriptSecurityManager so we avoid having necko
 // know about script security manager.
 #define NECKO_NO_APP_ID 0
 #define NECKO_UNKNOWN_APP_ID UINT32_MAX
-// special app id reserved for separating the safebrowsing cookie
-#define NECKO_SAFEBROWSING_APP_ID UINT32_MAX - 1
+
+// Unique first-party domain for separating the safebrowsing cookie.
+// Note if this value is changed, code in test_cookiejars_safebrowsing.js and
+// xml-fetcher.js should also be changed.
+#define NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN \
+  "safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla"
 
 /**
  * Determines whether appcache should be checked for a given URI.
  */
 bool NS_ShouldCheckAppCache(nsIURI *aURI, bool usePrivateBrowsing);
 
 bool NS_ShouldCheckAppCache(nsIPrincipal *aPrincipal, bool usePrivateBrowsing);
 
--- a/netwerk/test/unit/test_cookiejars_safebrowsing.js
+++ b/netwerk/test/unit/test_cookiejars_safebrowsing.js
@@ -1,19 +1,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Description of the test:
  *   We show that we can separate the safebrowsing cookie by creating a custom
- *   OriginAttributes using a reserved AppId (UINT_32_MAX - 1). Setting this
+ *   OriginAttributes using a unique safebrowsing first-party domain. Setting this
  *   custom OriginAttributes on the loadInfo of the channel allows us to query the
- *   AppId and therefore separate the safebrowing cookie in its own cookie-jar.
- *   For testing safebrowsing update we do >> NOT << emulate a response
+ *   first-party domain and therefore separate the safebrowing cookie in its own
+ *   cookie-jar. For testing safebrowsing update we do >> NOT << emulate a response
  *   in the body, rather we only set the cookies in the header of the response
  *   and confirm that cookies are separated in their own cookie-jar.
  *
  * 1) We init safebrowsing and simulate an update (cookies are set for localhost)
  *
  * 2) We open a channel that should send regular cookies, but not the
  *    safebrowsing cookie.
  *
@@ -143,17 +143,19 @@ add_test(function test_non_safebrowsing_
   }
 
   setNonSafeBrowsingCookie();
 });
 
 add_test(function test_safebrowsing_cookie() {
 
   var cookieName = 'sbCookie_id4294967294';
-  var originAttributes = new OriginAttributes(Ci.nsIScriptSecurityManager.SAFEBROWSING_APP_ID, false, 0);
+  var originAttributes = new OriginAttributes(0, false, 0);
+  originAttributes.firstPartyDomain =
+    "safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla";
 
   function setSafeBrowsingCookie() {
     var channel = setupChannel(setCookiePath, originAttributes);
     channel.setRequestHeader("set-cookie", cookieName, false);
     channel.asyncOpen2(new ChannelListener(checkSafeBrowsingCookie, null));
   }
 
   function checkSafeBrowsingCookie() {
--- a/toolkit/components/downloads/ApplicationReputation.cpp
+++ b/toolkit/components/downloads/ApplicationReputation.cpp
@@ -1273,41 +1273,34 @@ PendingLookup::SendRemoteQueryInternal()
                         nullptr, // aTriggeringPrincipal
                         nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                         nsIContentPolicy::TYPE_OTHER,
                         getter_AddRefs(mChannel));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
   if (loadInfo) {
-    loadInfo->SetOriginAttributes(
-      mozilla::NeckoOriginAttributes(false));
+    mozilla::NeckoOriginAttributes neckoAttrs(false);
+    neckoAttrs.mFirstPartyDomain.AssignLiteral(NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN);
+    loadInfo->SetOriginAttributes(neckoAttrs);
   }
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
   mozilla::Unused << httpChannel;
 
   // Upload the protobuf to the application reputation service.
   nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = uploadChannel->ExplicitSetUploadStream(sstream,
     NS_LITERAL_CSTRING("application/octet-stream"), serialized.size(),
     NS_LITERAL_CSTRING("POST"), false);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Set the Safebrowsing cookie jar, so that the regular Google cookie is not
-  // sent with this request. See bug 897516.
-  DocShellOriginAttributes attrs;
-  attrs.mAppId = NECKO_SAFEBROWSING_APP_ID;
-  nsCOMPtr<nsIInterfaceRequestor> loadContext = new mozilla::LoadContext(attrs);
-  rv = mChannel->SetNotificationCallbacks(loadContext);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   uint32_t timeoutMs = Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT, 10000);
   mTimeoutTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
   mTimeoutTimer->InitWithCallback(this, timeoutMs, nsITimer::TYPE_ONE_SHOT);
 
   rv = mChannel->AsyncOpen2(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
--- a/toolkit/components/url-classifier/content/xml-fetcher.js
+++ b/toolkit/components/url-classifier/content/xml-fetcher.js
@@ -29,24 +29,25 @@ this.PROT_NewXMLHttpRequest = function P
 /**
  * A helper class that does HTTP GETs and calls back a function with
  * the content it receives. Asynchronous, so uses a closure for the
  * callback.
  *
  * Note, that XMLFetcher is only used for SafeBrowsing, therefore
  * we inherit from nsILoadContext, so we can use the callbacks on the
  * channel to separate the safebrowsing cookie based on a reserved
- * appId.
+ * first-party domain.
  * @constructor
  */
 this.PROT_XMLFetcher = function PROT_XMLFetcher() {
   this.debugZone = "xmlfetcher";
   this._request = PROT_NewXMLHttpRequest();
   // implements nsILoadContext
-  this.appId = Ci.nsIScriptSecurityManager.SAFEBROWSING_APP_ID;
+  this.firstPartyDomain =
+    "safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla";
   this.isInIsolatedMozBrowserElement = false;
   this.usePrivateBrowsing = false;
   this.isContent = false;
 }
 
 PROT_XMLFetcher.prototype = {
   /**
    * Function that will be called back upon fetch completion.
@@ -61,17 +62,17 @@ PROT_XMLFetcher.prototype = {
    * @param callback Function to call back when complete.
    */
   get: function(page, callback) {
     this._request.abort();                // abort() is asynchronous, so
     this._request = PROT_NewXMLHttpRequest();
     this._callback = callback;
     var asynchronous = true;
     this._request.loadInfo.originAttributes = {
-      appId: this.appId,
+      firstPartyDomain: this.firstPartyDomain,
       inIsolatedMozBrowser: this.isInIsolatedMozBrowserElement
     };
     this._request.open("GET", page, asynchronous);
     this._request.channel.notificationCallbacks = this;
 
     // Create a closure
     var self = this;
     this._request.addEventListener("readystatechange", function() {
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
@@ -125,17 +125,19 @@ nsUrlClassifierStreamUpdater::FetchUpdat
                      nsIContentPolicy::TYPE_OTHER,
                      nullptr,  // aLoadGroup
                      this,     // aInterfaceRequestor
                      loadFlags);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
-  loadInfo->SetOriginAttributes(mozilla::NeckoOriginAttributes(false));
+  mozilla::NeckoOriginAttributes neckoAttrs(false);
+  neckoAttrs.mFirstPartyDomain.AssignLiteral(NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN);
+  loadInfo->SetOriginAttributes(neckoAttrs);
 
   mBeganStream = false;
 
   if (!aIsPostRequest) {
     // We use POST method to send our request in v2. In v4, the request
     // needs to be embedded to the URL and use GET method to send.
     // However, from the Chromium source code, a extended HTTP header has
     // to be sent along with the request to make the request succeed.
@@ -169,25 +171,16 @@ nsUrlClassifierStreamUpdater::FetchUpdat
 
     // Disable keepalive.
     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Connection"), NS_LITERAL_CSTRING("close"), false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  // Create a custom LoadContext for SafeBrowsing, so we can use callbacks on
-  // the channel to query the appId which allows separation of safebrowsing
-  // cookies in a separate jar.
-  DocShellOriginAttributes attrs;
-  attrs.mAppId = NECKO_SAFEBROWSING_APP_ID;
-  nsCOMPtr<nsIInterfaceRequestor> sbContext = new mozilla::LoadContext(attrs);
-  rv = mChannel->SetNotificationCallbacks(sbContext);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   // Make the request.
   rv = mChannel->AsyncOpen2(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mStreamTable = aStreamTable;
 
   return NS_OK;
 }