Bug 1452496: Discard same-site cookie in cross site context. r=dveditz
☠☠ backed out by 7a6977dca03a ☠ ☠
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Tue, 10 Apr 2018 17:17:49 +0200
changeset 412665 8bf36c469e228df416e1bfd80e753de36f47b6f1
parent 412664 e4200189c8ae7c4afa4668afe4580b4b5f42550e
child 412666 071ecf5e36808e9f9a96e15a0d019418a8846d5b
push id62460
push useraiakab@mozilla.com
push dateTue, 10 Apr 2018 22:13:15 +0000
treeherderautoland@14c7879f7eb7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdveditz
bugs1452496
milestone61.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 1452496: Discard same-site cookie in cross site context. r=dveditz
netwerk/cookie/nsCookieService.cpp
netwerk/test/TestCookie.cpp
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -3464,16 +3464,27 @@ nsCookieService::CanSetCookie(nsIURI*   
   if (aLeaveSecureAlone && aCookieAttributes.isSecure && !isSecure) {
     COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
       "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 &&
+      aThirdPartyUtil) {
+    bool isThirdParty = true;
+    aThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isThirdParty);
+    if (isThirdParty) {
+      return newCookie;
+    }
+  }
+
   aSetCookie = true;
   return newCookie;
 }
 
 // processes a single cookie, and returns true if there are more cookies
 // to be processed
 bool
 nsCookieService::SetCookieInternal(nsIURI                        *aHostURI,
--- a/netwerk/test/TestCookie.cpp
+++ b/netwerk/test/TestCookie.cpp
@@ -14,16 +14,17 @@
 #include "nsNetUtil.h"
 #include "nsISimpleEnumerator.h"
 #include "nsServiceManagerUtils.h"
 #include "nsNetCID.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "mozilla/Unused.h"
 #include "nsIURI.h"
+#include "nsContentUtils.h"
 
 using mozilla::Unused;
 
 static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
 static NS_DEFINE_CID(kPrefServiceCID,   NS_PREFSERVICE_CID);
 
 // various pref strings
 static const char kCookiesPermissions[] = "network.cookie.cookieBehavior";
@@ -70,16 +71,43 @@ SetACookie(nsICookieService *aCookieServ
     NS_NewURI(getter_AddRefs(uri1), aSpec1);
     if (aSpec2)
         NS_NewURI(getter_AddRefs(uri2), aSpec2);
 
     nsresult rv = aCookieService->SetCookieStringFromHttp(uri1, uri2, nullptr, (char *)aCookieString, aServerTime, nullptr);
     EXPECT_TRUE(NS_SUCCEEDED(rv));
 }
 
+// Custom Cookie Generator specifically for the needs of same-site cookies!
+// Hands off unless you know exactly what you are doing!
+void
+SetASameSiteCookie(nsICookieService *aCookieService, const char *aSpec1, const char *aSpec2, const char* aCookieString, const char *aServerTime)
+{
+    nsCOMPtr<nsIURI> uri1, uri2;
+    NS_NewURI(getter_AddRefs(uri1), aSpec1);
+    if (aSpec2)
+        NS_NewURI(getter_AddRefs(uri2), aSpec2);
+
+    // We create a dummy channel using the aSpec1 to simulate same-siteness
+    nsCOMPtr<nsIScriptSecurityManager> ssm = nsContentUtils::GetSecurityManager();
+    nsCOMPtr<nsIPrincipal> spec1Principal;
+    nsCString tmpString(aSpec1);
+    ssm->CreateCodebasePrincipalFromOrigin(tmpString, getter_AddRefs(spec1Principal));
+
+    nsCOMPtr<nsIChannel> dummyChannel;
+    NS_NewChannel(getter_AddRefs(dummyChannel),
+                  uri1,
+                  spec1Principal,
+                  nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
+                  nsIContentPolicy::TYPE_OTHER);
+
+    nsresult rv = aCookieService->SetCookieStringFromHttp(uri1, uri2, nullptr, (char *)aCookieString, aServerTime, dummyChannel);
+    EXPECT_TRUE(NS_SUCCEEDED(rv));
+}
+
 void
 SetACookieNoHttp(nsICookieService *aCookieService, const char *aSpec, const char* aCookieString)
 {
     nsCOMPtr<nsIURI> uri;
     NS_NewURI(getter_AddRefs(uri), aSpec);
 
     nsresult rv = aCookieService->SetCookieString(uri, nullptr, (char *)aCookieString, nullptr);
     EXPECT_TRUE(NS_SUCCEEDED(rv));
@@ -768,27 +796,27 @@ TEST(TestCookie,TestCookieMain)
 
 
     // *** SameSite attribute - parsing and cookie storage tests
     // Clear the cookies
     EXPECT_TRUE(NS_SUCCEEDED(cookieMgr->RemoveAll()));
 
     // Set cookies with various incantations of the samesite attribute:
     // No same site attribute present
-    SetACookie(cookieService, "http://samesite.test", nullptr, "unset=yes", nullptr);
+    SetASameSiteCookie(cookieService, "http://samesite.test", nullptr, "unset=yes", nullptr);
     // samesite attribute present but with no value
-    SetACookie(cookieService, "http://samesite.test", nullptr, "unspecified=yes; samesite", nullptr);
+    SetASameSiteCookie(cookieService, "http://samesite.test", nullptr, "unspecified=yes; samesite", nullptr);
     // samesite attribute present but with an empty value
-    SetACookie(cookieService, "http://samesite.test", nullptr, "empty=yes; samesite=", nullptr);
+    SetASameSiteCookie(cookieService, "http://samesite.test", nullptr, "empty=yes; samesite=", nullptr);
     // samesite attribute present but with an invalid value
-    SetACookie(cookieService, "http://samesite.test", nullptr, "bogus=yes; samesite=bogus", nullptr);
+    SetASameSiteCookie(cookieService, "http://samesite.test", nullptr, "bogus=yes; samesite=bogus", nullptr);
     // samesite=strict
-    SetACookie(cookieService, "http://samesite.test", nullptr, "strict=yes; samesite=strict", nullptr);
+    SetASameSiteCookie(cookieService, "http://samesite.test", nullptr, "strict=yes; samesite=strict", nullptr);
     // samesite=lax
-    SetACookie(cookieService, "http://samesite.test", nullptr, "lax=yes; samesite=lax", nullptr);
+    SetASameSiteCookie(cookieService, "http://samesite.test", nullptr, "lax=yes; samesite=lax", nullptr);
 
     EXPECT_TRUE(NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))));
     i = 0;
 
     // check the cookies for the required samesite value
     while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
       nsCOMPtr<nsISupports> cookie;
       if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break;