Bug 1452699 - Add a temporary pref to disable same-site cookies. r?valentin,r?ckerschb draft
authorFrancois Marier <francois@mozilla.com>
Fri, 13 Apr 2018 18:52:28 -0700
changeset 782063 3df5c2707c8bccf8a8a541cd418d2329f96a9dcd
parent 782062 57762f9ea1435f5860cd6da76f88eac023292112
push id106472
push userfmarier@mozilla.com
push dateSat, 14 Apr 2018 01:58:50 +0000
reviewersvalentin, ckerschb
bugs1452699
milestone61.0a1
Bug 1452699 - Add a temporary pref to disable same-site cookies. r?valentin,r?ckerschb MozReview-Commit-ID: LRnaSmdSgVW
dom/security/test/general/test_same_site_cookies_cross_origin_context.html
dom/security/test/general/test_same_site_cookies_from_script.html
dom/security/test/general/test_same_site_cookies_subrequest.html
dom/security/test/general/test_same_site_cookies_toplevel_nav.html
modules/libpref/init/all.js
netwerk/cookie/CookieServiceChild.cpp
netwerk/cookie/nsCookieService.cpp
netwerk/cookie/nsCookieService.h
--- a/dom/security/test/general/test_same_site_cookies_cross_origin_context.html
+++ b/dom/security/test/general/test_same_site_cookies_cross_origin_context.html
@@ -19,36 +19,55 @@
  *    in the context of http://mochi.test
  * 2) We load an iframe from http://example.com and check if the cookie
  *    is available.
  * 3) We observe that:
  *    (a) same site cookie has been discarded in a cross origin context.
  *    (b) the regular cookie is available.
  */
 
+SimpleTest.registerCleanupFunction(() => {
+  SpecialPowers.clearUserPref("network.cookie.same-site.enabled");
+});
 SimpleTest.waitForExplicitFinish();
 
 const CROSS_ORIGIN = "http://example.com/";
 const PATH = "tests/dom/security/test/general/file_same_site_cookies_cross_origin_context.sjs";
 
 let curTest = 0;
 
 var tests = [
   {
-    description: "regular cookie in cross origin context",
+    description: "regular cookie in cross origin context (same-site: on)",
     imgSRC: CROSS_ORIGIN + PATH + "?setRegularCookie",
     frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=regularCookie",
   },
   {
-    description: "same-site cookie in cross origin context",
+    description: "same-site cookie in cross origin context (same-site: on)",
     imgSRC: CROSS_ORIGIN + PATH + "?setSameSiteCookie",
     frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "", // no cookie should be set
   },
+  {
+    description: "regular cookie in cross origin context (same-site: off)",
+    imgSRC: CROSS_ORIGIN + PATH + "?setRegularCookie",
+    frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=regularCookie",
+  },
+  {
+    description: "same-site cookie in cross origin context (same-site: off)",
+    imgSRC: CROSS_ORIGIN + PATH + "?setSameSiteCookie",
+    frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=strictSameSiteCookie",
+  },
 ];
 
 
 window.addEventListener("message", receiveMessage);
 function receiveMessage(event) {
   is(event.data.result, tests[curTest].result, tests[curTest].description);
   curTest += 1;
 
@@ -63,16 +82,17 @@ function receiveMessage(event) {
 }
 
 function setupQueryResultAndRunTest() {
   let testframe = document.getElementById("testframe");
   testframe.src = tests[curTest].frameSRC + curTest;
 }
 
 function setCookieAndInitTest() {
+  SpecialPowers.setBoolPref("network.cookie.same-site.enabled", tests[curTest].sameSiteEnabled);
   var cookieImage = document.getElementById("cookieImage");
   cookieImage.onload = function() {
     ok(true, "trying to set cookie for test (" + tests[curTest].description + ")");
     setupQueryResultAndRunTest();
   }
   cookieImage.onerror = function() {
     ok(false, "could not load image for test (" + tests[curTest].description + ")");
   }
--- a/dom/security/test/general/test_same_site_cookies_from_script.html
+++ b/dom/security/test/general/test_same_site_cookies_from_script.html
@@ -18,37 +18,56 @@
  *    inline script in top-level context of http://mochi.test.
  * 2) We load an iframe from http://example.com and check if the cookie
  *    is available.
  * 3) We observe that:
  *    (a) same site cookie is available in same origin context.
  *    (a) same site cookie has been discarded in a cross origin context.
  */
 
+SimpleTest.registerCleanupFunction(() => {
+  SpecialPowers.clearUserPref("network.cookie.same-site.enabled");
+});
 SimpleTest.waitForExplicitFinish();
 
 const SAME_ORIGIN = "http://mochi.test:8888/";
 const CROSS_ORIGIN = "http://example.com/";
 const PATH = "tests/dom/security/test/general/file_same_site_cookies_from_script.sjs";
 
 let curTest = 0;
 
 var tests = [
   {
     description: "same-site cookie inline script within same-site context",
     setCookieSrc: SAME_ORIGIN + PATH + "?setSameSiteCookieUsingInlineScript",
     getCookieSrc: SAME_ORIGIN + PATH + "?getCookieFrame",
+    sameSiteEnabled: true,
     result: "myKey=sameSiteCookieInlineScript",
   },
   {
     description: "same-site cookie inline script within cross-site context",
     setCookieSrc: CROSS_ORIGIN + PATH + "?setSameSiteCookieUsingInlineScript",
     getCookieSrc: CROSS_ORIGIN + PATH + "?getCookieFrame",
+    sameSiteEnabled: true,
     result: "", // same-site cookie should be discarded in cross site context
   },
+  {
+    description: "same-site cookie inline script within same-site context",
+    setCookieSrc: SAME_ORIGIN + PATH + "?setSameSiteCookieUsingInlineScript",
+    getCookieSrc: SAME_ORIGIN + PATH + "?getCookieFrame",
+    sameSiteEnabled: false,
+    result: "myKey=sameSiteCookieInlineScript",
+  },
+  {
+    description: "same-site cookie inline script within cross-site context",
+    setCookieSrc: CROSS_ORIGIN + PATH + "?setSameSiteCookieUsingInlineScript",
+    getCookieSrc: CROSS_ORIGIN + PATH + "?getCookieFrame",
+    sameSiteEnabled: false,
+    result: "myKey=sameSiteCookieInlineScript",
+  },
 ];
 
 window.addEventListener("message", receiveMessage);
 function receiveMessage(event) {
   is(event.data.result, tests[curTest].result, tests[curTest].description);
   curTest += 1;
 
   // lets see if we ran all the tests
@@ -62,16 +81,17 @@ function receiveMessage(event) {
 }
 
 function setupQueryResultAndRunTest() {
   let getCookieFrame = document.getElementById("getCookieFrame");
   getCookieFrame.src = tests[curTest].getCookieSrc + curTest;
 }
 
 function setCookieAndInitTest() {
+  SpecialPowers.setBoolPref("network.cookie.same-site.enabled", tests[curTest].sameSiteEnabled);
   var cookieFrame = document.getElementById("setCookieFrame");
   setCookieFrame.onload = function() {
     ok(true, "trying to set cookie for test (" + tests[curTest].description + ")");
     setupQueryResultAndRunTest();
   }
   setCookieFrame.onerror = function() {
     ok(false, "could not load image for test (" + tests[curTest].description + ")");
   }
--- a/dom/security/test/general/test_same_site_cookies_subrequest.html
+++ b/dom/security/test/general/test_same_site_cookies_subrequest.html
@@ -22,49 +22,84 @@
  *
  * In detail:
  * We perform an XHR request to the *.sjs file which is processed async on
  * the server and waits till the image request has been processed by the server.
  * Once the image requets was processed, the server responds to the initial
  * XHR request with the expecuted result (the cookie value).
  */
 
+SimpleTest.registerCleanupFunction(() => {
+  SpecialPowers.clearUserPref("network.cookie.same-site.enabled");
+});
 SimpleTest.waitForExplicitFinish();
 
 const SAME_ORIGIN = "http://mochi.test:8888/";
 const CROSS_ORIGIN = "http://example.com/";
 const PATH = "tests/dom/security/test/general/file_same_site_cookies_subrequest.sjs";
 
 let curTest = 0;
 
 var tests = [
   {
     description: "same origin site using cookie policy 'samesite=strict'",
     imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
     frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=strictSameSiteCookie",
   },
   {
     description: "cross origin site using cookie policy 'samesite=strict'",
     imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
     frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=noCookie",
   },
   {
     description: "same origin site using cookie policy 'samesite=lax'",
     imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
     frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=laxSameSiteCookie",
   },
   {
     description: "cross origin site using cookie policy 'samesite=lax'",
     imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
     frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=noCookie",
   },
+  {
+    description: "same origin site using cookie policy 'samesite=strict'",
+    imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
+    frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=strictSameSiteCookie",
+  },
+  {
+    description: "cross origin site using cookie policy 'samesite=strict'",
+    imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
+    frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=strictSameSiteCookie",
+  },
+  {
+    description: "same origin site using cookie policy 'samesite=lax'",
+    imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
+    frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=laxSameSiteCookie",
+  },
+  {
+    description: "cross origin site using cookie policy 'samesite=lax'",
+    imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
+    frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=laxSameSiteCookie",
+  },
 ];
 
 function checkResult(aCookieVal) {
   is(aCookieVal, tests[curTest].result, tests[curTest].description);
   curTest += 1;
 
   // lets see if we ran all the tests
   if (curTest == tests.length) {
@@ -89,16 +124,17 @@ function setupQueryResultAndRunTest() {
   // give it some time and load the test frame
   SimpleTest.executeSoon(function() {
     let testframe = document.getElementById("testframe");
     testframe.src = tests[curTest].frameSRC + curTest;
   });
 }
 
 function setCookieAndInitTest() {
+  SpecialPowers.setBoolPref("network.cookie.same-site.enabled", tests[curTest].sameSiteEnabled);
   var cookieImage = document.getElementById("cookieImage");
   cookieImage.onload = function() {
     ok(true, "set cookie for test (" + tests[curTest].description + ")");
     setupQueryResultAndRunTest();
   }
   cookieImage.onerror = function() {
     ok(false, "could not set cookie for test (" + tests[curTest].description + ")");
   }
--- a/dom/security/test/general/test_same_site_cookies_toplevel_nav.html
+++ b/dom/security/test/general/test_same_site_cookies_toplevel_nav.html
@@ -23,47 +23,82 @@
  *
  * In detail:
  * We perform an XHR request to the *.sjs file which is processed async on
  * the server and waits till the image request has been processed by the server.
  * Once the image requets was processed, the server responds to the initial
  * XHR request with the expecuted result (the cookie value).
  */
 
+SimpleTest.registerCleanupFunction(() => {
+  SpecialPowers.clearUserPref("network.cookie.same-site.enabled");
+});
 SimpleTest.waitForExplicitFinish();
 
 const SAME_ORIGIN = "http://mochi.test:8888/";
 const CROSS_ORIGIN = "http://example.com/";
 const PATH = "tests/dom/security/test/general/file_same_site_cookies_toplevel_nav.sjs";
 
 let curTest = 0;
 
 var tests = [
   {
     description: "same origin navigation using cookie policy 'samesite=strict'",
     imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
     frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=strictSameSiteCookie",
   },
   {
     description: "cross origin navigation using cookie policy 'samesite=strict'",
     imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
     frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=noCookie",
   },
   {
     description: "same origin navigation using cookie policy 'samesite=lax'",
     imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
     frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
     result: "myKey=laxSameSiteCookie",
   },
   {
     description: "cross origin navigation using cookie policy 'samesite=lax'",
     imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
     frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: true,
+    result: "myKey=laxSameSiteCookie",
+  },
+  {
+    description: "same origin navigation using cookie policy 'samesite=strict'",
+    imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
+    frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=strictSameSiteCookie",
+  },
+  {
+    description: "cross origin navigation using cookie policy 'samesite=strict'",
+    imgSRC: SAME_ORIGIN + PATH + "?setStrictSameSiteCookie",
+    frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=strictSameSiteCookie",
+  },
+  {
+    description: "same origin navigation using cookie policy 'samesite=lax'",
+    imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
+    frameSRC: SAME_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
+    result: "myKey=laxSameSiteCookie",
+  },
+  {
+    description: "cross origin navigation using cookie policy 'samesite=lax'",
+    imgSRC: SAME_ORIGIN + PATH + "?setLaxSameSiteCookie",
+    frameSRC: CROSS_ORIGIN + PATH + "?loadFrame",
+    sameSiteEnabled: false,
     result: "myKey=laxSameSiteCookie",
   },
 ];
 
 function checkResult(aCookieVal) {
   is(aCookieVal, tests[curTest].result, tests[curTest].description);
   curTest += 1;
 
@@ -90,16 +125,17 @@ function setupQueryResultAndRunTest() {
   // give it some time and load the test window
   SimpleTest.executeSoon(function() {
     let testframe = document.getElementById("testframe");
     testframe.src = tests[curTest].frameSRC + curTest;
   });
 }
 
 function setCookieAndInitTest() {
+  SpecialPowers.setBoolPref("network.cookie.same-site.enabled", tests[curTest].sameSiteEnabled);
   var cookieImage = document.getElementById("cookieImage");
   cookieImage.onload = function() {
     ok(true, "set cookie for test (" + tests[curTest].description + ")");
     setupQueryResultAndRunTest();
   }
   cookieImage.onerror = function() {
     ok(false, "could not set cookie for test (" + tests[curTest].description + ")");
   }
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2221,16 +2221,17 @@ pref("network.proxy.failover_timeout",  
 pref("network.online",                      true); //online/offline
 pref("network.cookie.cookieBehavior",       0); // 0-Accept, 1-dontAcceptForeign, 2-dontAcceptAny, 3-limitForeign
 #ifdef ANDROID
 pref("network.cookie.cookieBehavior",       0); // Keep the old default of accepting all cookies
 #endif
 pref("network.cookie.thirdparty.sessionOnly", false);
 pref("network.cookie.thirdparty.nonsecureSessionOnly", false);
 pref("network.cookie.leave-secure-alone",   true);
+pref("network.cookie.same-site.enabled",    true); // Honor the SameSite cookie attribute
 pref("network.cookie.ipc.sync",             false);
 pref("network.cookie.lifetimePolicy",       0); // 0-accept, 1-dontUse 2-acceptForSession, 3-acceptForNDays
 pref("network.cookie.prefsMigrated",        false);
 pref("network.cookie.lifetime.days",        90); // Ignored unless network.cookie.lifetimePolicy is 3.
 
 // The PAC file to load.  Ignored unless network.proxy.type is 2.
 pref("network.proxy.autoconfig_url", "");
 // Strip off paths when sending URLs to PAC scripts
--- a/netwerk/cookie/CookieServiceChild.cpp
+++ b/netwerk/cookie/CookieServiceChild.cpp
@@ -309,17 +309,17 @@ CookieServiceChild::GetCookieStringFromC
       continue;
 
     // if the cookie is secure and the host scheme isn't, we can't send it
     if (cookie->IsSecure() && !isSecure)
       continue;
 
     int32_t sameSiteAttr = 0;
     cookie->GetSameSite(&sameSiteAttr);
-    if (aIsSameSiteForeign) {
+    if (aIsSameSiteForeign && nsCookieService::IsSameSiteEnabled()) {
       // it if's a cross origin request and the cookie is same site only (strict)
       // don't send it
       if (sameSiteAttr == nsICookie2::SAMESITE_STRICT) {
         continue;
       }
       // if it's a cross origin request, the cookie is same site lax, but it's not
       // a top-level navigation, don't send it
       if (sameSiteAttr == nsICookie2::SAMESITE_LAX && !aIsSafeTopLevelNav) {
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -71,16 +71,17 @@ using namespace mozilla::net;
         nsCookieKey(baseDomain, OriginAttributes())
 
 /******************************************************************************
  * nsCookieService impl:
  * useful types & constants
  ******************************************************************************/
 
 static StaticRefPtr<nsCookieService> gCookieService;
+bool nsCookieService::sSameSiteEnabled = false;
 
 // XXX_hack. See bug 178993.
 // This is a hack to hide HttpOnly cookies from older browsers
 #define HTTP_ONLY_PREFIX "#HttpOnly_"
 
 #define COOKIES_FILE "cookies.sqlite"
 #define COOKIES_SCHEMA_VERSION 9
 
@@ -3070,16 +3071,28 @@ nsCookieService::DomainMatches(nsCookie*
   // first, check for an exact host or domain cookie match, e.g. "google.com"
   // or ".google.com"; second a subdomain match, e.g.
   // host = "mail.google.com", cookie domain = ".google.com".
   return aCookie->RawHost() == aHost ||
       (aCookie->IsDomain() && StringEndsWith(aHost, aCookie->Host()));
 }
 
 bool
+nsCookieService::IsSameSiteEnabled()
+{
+  static bool prefInitialized = false;
+  if (!prefInitialized) {
+    Preferences::AddBoolVarCache(&sSameSiteEnabled,
+                                 "network.cookie.same-site.enabled", false);
+    prefInitialized = true;
+  }
+  return sSameSiteEnabled;
+}
+
+bool
 nsCookieService::PathMatches(nsCookie* aCookie,
                              const nsACString& aPath)
 {
   // calculate cookie path length, excluding trailing '/'
   uint32_t cookiePathLen = aCookie->Path().Length();
   if (cookiePathLen > 0 && aCookie->Path().Last() == '/')
     --cookiePathLen;
 
@@ -3199,17 +3212,17 @@ nsCookieService::GetCookiesForURI(nsIURI
       continue;
 
     // if the cookie is secure and the host scheme isn't, we can't send it
     if (cookie->IsSecure() && !isSecure)
       continue;
 
     int32_t sameSiteAttr = 0;
     cookie->GetSameSite(&sameSiteAttr);
-    if (aIsSameSiteForeign) {
+    if (aIsSameSiteForeign && IsSameSiteEnabled()) {
       // it if's a cross origin request and the cookie is same site only (strict)
       // don't send it
       if (sameSiteAttr == nsICookie2::SAMESITE_STRICT) {
         continue;
       }
       // if it's a cross origin request, the cookie is same site lax, but it's not
       // a top-level navigation, don't send it
       if (sameSiteAttr == nsICookie2::SAMESITE_LAX && !aIsSafeTopLevelNav) {
@@ -3466,17 +3479,18 @@ nsCookieService::CanSetCookie(nsIURI*   
       "non-https cookie can't set secure flag");
     Telemetry::Accumulate(Telemetry::COOKIE_LEAVE_SECURE_ALONE,
                           BLOCKED_SECURE_SET_FROM_HTTP);
     return newCookie;
   }
 
   // If the new cookie is same-site but in a cross site context,
   // browser must ignore the cookie.
-  if (aCookieAttributes.sameSite != nsICookie2::SAMESITE_UNSET) {
+  if ((aCookieAttributes.sameSite != nsICookie2::SAMESITE_UNSET) &&
+      IsSameSiteEnabled()) {
     bool isThirdParty = NS_IsSameSiteForeign(aChannel, aHostURI);
     if (isThirdParty) {
       COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
                         "failed the samesite tests");
       return newCookie;
     }
   }
 
--- a/netwerk/cookie/nsCookieService.h
+++ b/netwerk/cookie/nsCookieService.h
@@ -241,16 +241,18 @@ class nsCookieService final : public nsI
                             , public nsICookieManager
                             , public nsIObserver
                             , public nsSupportsWeakReference
                             , public nsIMemoryReporter
 {
   private:
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
+    static bool sSameSiteEnabled; // cached pref
+
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
     NS_DECL_NSICOOKIESERVICE
     NS_DECL_NSICOOKIEMANAGER
     NS_DECL_NSIMEMORYREPORTER
 
     nsCookieService();
@@ -263,16 +265,17 @@ class nsCookieService final : public nsI
    * (thus instantiating it, if necessary) and clear all the cookies for that
    * app.
    */
   static void AppClearDataObserverInit();
   static nsCString GetPathFromURI(nsIURI *aHostURI);
   static nsresult GetBaseDomain(nsIEffectiveTLDService *aTLDService, nsIURI *aHostURI, nsCString &aBaseDomain, bool &aRequireHostMatch);
   static nsresult GetBaseDomainFromHost(nsIEffectiveTLDService *aTLDService, const nsACString &aHost, nsCString &aBaseDomain);
   static bool DomainMatches(nsCookie* aCookie, const nsACString& aHost);
+  static bool IsSameSiteEnabled();
   static bool PathMatches(nsCookie* aCookie, const nsACString& aPath);
   static bool CanSetCookie(nsIURI *aHostURI, const nsCookieKey& aKey, nsCookieAttributes &aCookieAttributes, bool aRequireHostMatch, CookieStatus aStatus, nsDependentCString &aCookieHeader, int64_t aServerTime, bool aFromHttp, nsIChannel* aChannel, bool aLeaveSercureAlone, bool &aSetCookie, mozIThirdPartyUtil* aThirdPartyUtil);
   static CookieStatus CheckPrefs(nsICookiePermission *aPermissionServices, uint8_t aCookieBehavior, bool aThirdPartySession, bool aThirdPartyNonsecureSession, nsIURI *aHostURI, bool aIsForeign, const char *aCookieHeader, const int aNumOfCookies, const OriginAttributes& aOriginAttrs);
   static int64_t ParseServerTime(const nsCString &aServerTime);
   void GetCookiesForURI(nsIURI *aHostURI, bool aIsForeign, bool aIsSafeTopLevelNav, bool aIsTopLevelForeign, bool aHttpBound, const OriginAttributes& aOriginAttrs, nsTArray<nsCookie*>& aCookieList);
 
   protected:
     virtual ~nsCookieService();