From 9197c15057f0e85bd16259aa9243ab82d048ad43 Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Sun, 16 Apr 2023 14:58:40 -0700 Subject: [PATCH] #651: M1779993 + backbugs --- netwerk/cookie/nsCookieService.cpp | 61 ++++++++++++++++++++++++++++++ netwerk/cookie/nsCookieService.h | 2 + 2 files changed, 63 insertions(+) diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index 377d59576..df6fa7ad6 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -3224,11 +3224,13 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI, // 3 = secure and "https:" bool isHTTPS; nsresult rv = aHostURI->SchemeIs("https", &isHTTPS); +/* if (NS_SUCCEEDED(rv)) { Telemetry::Accumulate(Telemetry::COOKIE_SCHEME_SECURITY, ((cookieAttributes.isSecure)? 0x02 : 0x00) | ((isHTTPS)? 0x01 : 0x00)); } +*/ int64_t currentTimeInUsec = PR_Now(); @@ -3285,6 +3287,15 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI, return newCookie; } + if (!CheckHiddenPrefix(cookieAttributes)) { + COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "failed the CheckHiddenPrefix tests"); + return newCookie; + } + if (!CheckPrefixes(cookieAttributes, isHTTPS)) { + COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "failed the prefix tests"); + return newCookie; + } + // create a new nsCookie and copy attributes RefPtr cookie = nsCookie::Create(cookieAttributes.name, @@ -4108,6 +4119,56 @@ nsCookieService::CheckPath(nsCookieAttributes &aCookieAttributes, return true; } +bool +nsCookieService::CheckPrefixes(nsCookieAttributes &aCookieAttributes, + bool aSecureRequest) +{ + if (aCookieAttributes.name.IsEmpty() || aCookieAttributes.name.Length() == 0) + return true; + + bool isSecure = StringBeginsWith(aCookieAttributes.name, NS_LITERAL_CSTRING("__Secure-")); + bool isHost = StringBeginsWith(aCookieAttributes.name, NS_LITERAL_CSTRING("__Host-")); + + if (!isSecure && !isHost) { + // not one of the magic prefixes: carry on + return true; + } + + if (!aSecureRequest || !aCookieAttributes.isSecure) { + // the magic prefixes may only be used from a secure request and + // the secure attribute must be set on the cookie + return false; + } + + if (isHost) { + // The host prefix requires that the path is "/" and that the cookie + // had no domain attribute. CheckDomain() and CheckPath() MUST be run + // first to make sure invalid attributes are rejected and to regularlize + // them. In particular all explicit domain attributes result in a host + // that starts with a dot, and if the host doesn't start with a dot it + // correctly matches the true host. + if (aCookieAttributes.host[0] == '.' || + !aCookieAttributes.path.EqualsLiteral("/")) { + return false; + } + } + + return true; +} + +bool +nsCookieService::CheckHiddenPrefix(nsCookieAttributes &aCookieAttributes) +{ + if (aCookieAttributes.name.IsEmpty() || aCookieAttributes.name.Length() == 0) + return true; + if (StringBeginsWith(aCookieAttributes.value, NS_LITERAL_CSTRING("__Host-"))) + return false; + if (StringBeginsWith(aCookieAttributes.value, NS_LITERAL_CSTRING("__Secure-"))) + return false; + + return true; +} + bool nsCookieService::GetExpiry(nsCookieAttributes &aCookieAttributes, int64_t aServerTime, diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h index 27469f21c..8b28f6c25 100644 --- a/netwerk/cookie/nsCookieService.h +++ b/netwerk/cookie/nsCookieService.h @@ -309,6 +309,8 @@ class nsCookieService final : public nsICookieService CookieStatus CheckPrefs(nsIURI *aHostURI, bool aIsForeign, bool aRequireHostMatch, const char *aCookieHeader); bool CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, bool aRequireHostMatch); static bool CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI); + bool CheckPrefixes(nsCookieAttributes &aCookie, bool aSecureRequest); + bool CheckHiddenPrefix(nsCookieAttributes &aCookie); static bool GetExpiry(nsCookieAttributes &aCookie, int64_t aServerTime, int64_t aCurrentTime); void RemoveAllFromMemory(); already_AddRefed PurgeCookies(int64_t aCurrentTimeInUsec);