Bug 1320402 - Move url-classifier off of using appIds. r=ehsan, gcp
authordimi <dlee@mozilla.com>
Tue, 03 Jan 2017 14:21:58 +0800
changeset 327833 306a058214a2b8a0b61ddc733adcd2820bfcb3a9
parent 327832 91575284650d1e4fcb9e8bbac27ee379825475b7
child 327834 2bd53e4e662bcdd32c53cb4e09ceff088e8f6369
push id31155
push userphilringnalda@gmail.com
push dateWed, 04 Jan 2017 02:40:39 +0000
treeherdermozilla-central@57ac9f63fc69 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, gcp
bugs1320402
milestone53.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 1320402 - Move url-classifier off of using appIds. r=ehsan, gcp MozReview-Commit-ID: IqnAVrv2c9W
caps/BasePrincipal.h
caps/nsIScriptSecurityManager.idl
docshell/base/LoadContext.h
netwerk/base/LoadContextInfo.cpp
netwerk/base/nsNetUtil.h
netwerk/cache2/CacheFileUtils.cpp
netwerk/cookie/nsCookieService.cpp
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/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -132,19 +132,18 @@ public:
   InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs);
 };
 
 // For OriginAttributes stored on Necko.
 class NeckoOriginAttributes : public OriginAttributes
 {
 public:
   NeckoOriginAttributes() {}
-  NeckoOriginAttributes(uint32_t aAppId, bool aInIsolatedMozBrowser)
+  explicit NeckoOriginAttributes(bool aInIsolatedMozBrowser)
   {
-    mAppId = aAppId;
     mInIsolatedMozBrowser = aInIsolatedMozBrowser;
   }
 
   // Inheriting OriginAttributes from document to necko when a network request
   // is made.
   void InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs);
 
   // Inheriting OriginAttributes from a docshell when loading a top-level
--- 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/LoadContextInfo.cpp
+++ b/netwerk/base/LoadContextInfo.cpp
@@ -132,18 +132,17 @@ GetLoadContextInfo(nsIChannel * aChannel
 
   return new LoadContextInfo(anon, oa);
 }
 
 LoadContextInfo *
 GetLoadContextInfo(nsILoadContext *aLoadContext, bool aIsAnonymous)
 {
   if (!aLoadContext) {
-    return new LoadContextInfo(aIsAnonymous,
-                               NeckoOriginAttributes(nsILoadContextInfo::NO_APP_ID, false));
+    return new LoadContextInfo(aIsAnonymous, NeckoOriginAttributes(false));
   }
 
   DebugOnly<bool> pb = aLoadContext->UsePrivateBrowsing();
   DocShellOriginAttributes doa;
   aLoadContext->GetOriginAttributes(doa);
   MOZ_ASSERT(pb == (doa.mPrivateBrowsingId > 0));
 
   NeckoOriginAttributes noa;
--- 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
+// 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/cache2/CacheFileUtils.cpp
+++ b/netwerk/cache2/CacheFileUtils.cpp
@@ -30,17 +30,17 @@ namespace {
  * A simple recursive descent parser for the mapping key.
  */
 class KeyParser : protected Tokenizer
 {
 public:
   explicit KeyParser(nsACString const& aInput)
     : Tokenizer(aInput)
     // Initialize attributes to their default values
-    , originAttribs(0, false)
+    , originAttribs(false)
     , isAnonymous(false)
     // Initialize the cache key to a zero length by default
     , lastTag(0)
   {
   }
 
 private:
   // Results
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -829,26 +829,24 @@ class ConvertAppIdToOriginAttrsSQLFuncti
 
 NS_IMPL_ISUPPORTS(ConvertAppIdToOriginAttrsSQLFunction, mozIStorageFunction);
 
 NS_IMETHODIMP
 ConvertAppIdToOriginAttrsSQLFunction::OnFunctionCall(
   mozIStorageValueArray* aFunctionArguments, nsIVariant** aResult)
 {
   nsresult rv;
-  int32_t appId, inIsolatedMozBrowser;
-
-  rv = aFunctionArguments->GetInt32(0, &appId);
-  NS_ENSURE_SUCCESS(rv, rv);
+  int32_t inIsolatedMozBrowser;
+
   rv = aFunctionArguments->GetInt32(1, &inIsolatedMozBrowser);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Create an originAttributes object by appId and inIsolatedMozBrowser.
+  // Create an originAttributes object by inIsolatedMozBrowser.
   // Then create the originSuffix string from this object.
-  NeckoOriginAttributes attrs(appId, (inIsolatedMozBrowser ? 1 : 0));
+  NeckoOriginAttributes attrs((inIsolatedMozBrowser ? 1 : 0));
   nsAutoCString suffix;
   attrs.CreateSuffix(suffix);
 
   RefPtr<nsVariant> outVar(new nsVariant());
   rv = outVar->SetAsAUTF8String(suffix);
   NS_ENSURE_SUCCESS(rv, rv);
 
   outVar.forget(aResult);
--- 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(NECKO_SAFEBROWSING_APP_ID, 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
@@ -126,17 +126,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(NECKO_SAFEBROWSING_APP_ID, 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.
@@ -170,25 +172,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;
 }