Bug 1642971 - Support FTP scheme for cookies, r=mayhemer
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 10 Jun 2020 12:28:54 +0000
changeset 598933 855b849ec0908d03cc5db0ecbf5bd4a9d1ced1d1
parent 598932 cd2349a7928cc201cab350c4ee046fe11266c362
child 598934 0edbbe70c420684f0ae9c70da93f8b68db3cba60
push id13310
push userffxbld-merge
push dateMon, 29 Jun 2020 14:50:06 +0000
treeherdermozilla-beta@15a59a0afa5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1642971
milestone79.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 1642971 - Support FTP scheme for cookies, r=mayhemer Differential Revision: https://phabricator.services.mozilla.com/D78042
netwerk/cookie/CookieCommons.cpp
netwerk/cookie/CookieCommons.h
netwerk/cookie/CookieService.cpp
netwerk/cookie/CookieServiceChild.cpp
--- a/netwerk/cookie/CookieCommons.cpp
+++ b/netwerk/cookie/CookieCommons.cpp
@@ -346,16 +346,20 @@ already_AddRefed<Cookie> CookieCommons::
   auto* basePrincipal = BasePrincipal::Cast(aDocument->NodePrincipal());
   basePrincipal->GetURI(getter_AddRefs(principalURI));
   if (NS_WARN_IF(!principalURI)) {
     // Document's principal is not a content or null (may be system), so
     // can't set cookies
     return nullptr;
   }
 
+  if (!CookieCommons::IsSchemeSupported(principalURI)) {
+    return nullptr;
+  }
+
   nsAutoCString baseDomain;
   bool requireHostMatch = false;
   nsresult rv = CookieCommons::GetBaseDomain(aTLDService, principalURI,
                                              baseDomain, requireHostMatch);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
@@ -633,25 +637,59 @@ nsICookie::schemeType CookieCommons::Pri
   }
 
   return SchemeToSchemeType(scheme);
 }
 
 // static
 nsICookie::schemeType CookieCommons::SchemeToSchemeType(
     const nsACString& aScheme) {
+  MOZ_ASSERT(IsSchemeSupported(aScheme));
+
   if (aScheme.Equals("https")) {
     return nsICookie::SCHEME_HTTPS;
   }
 
   if (aScheme.Equals("http")) {
     return nsICookie::SCHEME_HTTP;
   }
 
   if (aScheme.Equals("file")) {
     return nsICookie::SCHEME_FILE;
   }
 
   MOZ_CRASH("Unsupported scheme type");
 }
 
+// static
+bool CookieCommons::IsSchemeSupported(nsIPrincipal* aPrincipal) {
+  MOZ_ASSERT(aPrincipal);
+
+  nsAutoCString scheme;
+  nsresult rv = aPrincipal->GetScheme(scheme);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return false;
+  }
+
+  return IsSchemeSupported(scheme);
+}
+
+// static
+bool CookieCommons::IsSchemeSupported(nsIURI* aURI) {
+  MOZ_ASSERT(aURI);
+
+  nsAutoCString scheme;
+  nsresult rv = aURI->GetScheme(scheme);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return false;
+  }
+
+  return IsSchemeSupported(scheme);
+}
+
+// static
+bool CookieCommons::IsSchemeSupported(const nsACString& aScheme) {
+  return aScheme.Equals("https") || aScheme.Equals("http") ||
+         aScheme.Equals("file");
+}
+
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/cookie/CookieCommons.h
+++ b/netwerk/cookie/CookieCommons.h
@@ -111,16 +111,20 @@ class CookieCommons final {
 
   static bool MaybeCompareSchemeWithLogging(nsIConsoleReportCollector* aCRC,
                                             nsIURI* aHostURI, Cookie* aCookie,
                                             nsICookie::schemeType aSchemeType);
 
   static bool MaybeCompareScheme(Cookie* aCookie,
                                  nsICookie::schemeType aSchemeType);
 
+  static bool IsSchemeSupported(nsIPrincipal* aPrincipal);
+  static bool IsSchemeSupported(nsIURI* aURI);
+  static bool IsSchemeSupported(const nsACString& aScheme);
+
   static nsICookie::schemeType URIToSchemeType(nsIURI* aURI);
 
   static nsICookie::schemeType PrincipalToSchemeType(nsIPrincipal* aPrincipal);
 
   static nsICookie::schemeType SchemeToSchemeType(const nsACString& aScheme);
 
   // Returns true if the channel is a safe top-level navigation or if it's a
   // download request
--- a/netwerk/cookie/CookieService.cpp
+++ b/netwerk/cookie/CookieService.cpp
@@ -279,16 +279,20 @@ CookieService::GetCookieStringFromDocume
   aCookie.Truncate();
 
   if (!IsInitialized()) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIPrincipal> principal = aDocument->EffectiveStoragePrincipal();
 
+  if (!CookieCommons::IsSchemeSupported(principal)) {
+    return NS_OK;
+  }
+
   nsICookie::schemeType schemeType =
       CookieCommons::PrincipalToSchemeType(principal);
 
   CookieStorage* storage = PickStorage(principal->OriginAttributesRef());
 
   nsAutoCString baseDomain;
   rv = CookieCommons::GetBaseDomain(principal, baseDomain);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -399,16 +403,20 @@ CookieService::GetCookieStringFromDocume
 NS_IMETHODIMP
 CookieService::GetCookieStringFromHttp(nsIURI* aHostURI, nsIChannel* aChannel,
                                        nsACString& aCookieString) {
   NS_ENSURE_ARG(aHostURI);
   NS_ENSURE_ARG(aChannel);
 
   aCookieString.Truncate();
 
+  if (!CookieCommons::IsSchemeSupported(aHostURI)) {
+    return NS_OK;
+  }
+
   uint32_t rejectedReason = 0;
   ThirdPartyAnalysisResult result = mThirdPartyUtil->AnalyzeChannel(
       aChannel, false, aHostURI, nullptr, &rejectedReason);
 
   OriginAttributes attrs;
   StoragePrincipalHelper::GetOriginAttributes(
       aChannel, attrs, StoragePrincipalHelper::eStorageAccessPrincipal);
 
@@ -489,16 +497,20 @@ CookieService::SetCookieStringFromHttp(n
                                        nsIChannel* aChannel) {
   NS_ENSURE_ARG(aHostURI);
   NS_ENSURE_ARG(aChannel);
 
   if (!IsInitialized()) {
     return NS_OK;
   }
 
+  if (!CookieCommons::IsSchemeSupported(aHostURI)) {
+    return NS_OK;
+  }
+
   uint32_t rejectedReason = 0;
   ThirdPartyAnalysisResult result = mThirdPartyUtil->AnalyzeChannel(
       aChannel, false, aHostURI, nullptr, &rejectedReason);
 
   OriginAttributes attrs;
   StoragePrincipalHelper::GetOriginAttributes(
       aChannel, attrs, StoragePrincipalHelper::eStorageAccessPrincipal);
 
@@ -1473,20 +1485,22 @@ CookieStatus CookieService::CheckPrefs(n
                                        const OriginAttributes& aOriginAttrs,
                                        uint32_t* aRejectedReason) {
   nsresult rv;
 
   MOZ_ASSERT(aRejectedReason);
 
   *aRejectedReason = 0;
 
-  // don't let ftp sites get/set cookies (could be a security issue)
-  if (aHostURI->SchemeIs("ftp")) {
+  // don't let unsupported scheme sites get/set cookies (could be a security
+  // issue)
+  if (!CookieCommons::IsSchemeSupported(aHostURI)) {
     COOKIE_LOGFAILURE(aCookieHeader.IsVoid() ? GET_COOKIE : SET_COOKIE,
-                      aHostURI, aCookieHeader, "ftp sites cannot read cookies");
+                      aHostURI, aCookieHeader,
+                      "non http/https sites cannot read cookies");
     return STATUS_REJECTED_WITH_ERROR;
   }
 
   nsCOMPtr<nsIPrincipal> principal =
       BasePrincipal::CreateContentPrincipal(aHostURI, aOriginAttrs);
 
   if (!principal) {
     COOKIE_LOGFAILURE(aCookieHeader.IsVoid() ? GET_COOKIE : SET_COOKIE,
--- a/netwerk/cookie/CookieServiceChild.cpp
+++ b/netwerk/cookie/CookieServiceChild.cpp
@@ -501,16 +501,20 @@ CookieServiceChild::SetCookieStringFromD
 
 NS_IMETHODIMP
 CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI,
                                             const nsACString& aCookieString,
                                             nsIChannel* aChannel) {
   NS_ENSURE_ARG(aHostURI);
   NS_ENSURE_ARG(aChannel);
 
+  if (!CookieCommons::IsSchemeSupported(aHostURI)) {
+    return NS_OK;
+  }
+
   // Fast past: don't bother sending IPC messages about nullprincipal'd
   // documents.
   nsAutoCString scheme;
   aHostURI->GetScheme(scheme);
   if (scheme.EqualsLiteral("moz-nullprincipal")) {
     return NS_OK;
   }