Bug 1891349 - Treat cookie name prefixes as case-insensitive r=dveditz,cookie-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D207412
This commit is contained in:
longsonr 2024-04-17 03:22:18 +00:00
parent c6f3ba47a6
commit b4f52c1006
11 changed files with 20 additions and 130 deletions

View File

@ -25,6 +25,7 @@
#include "mozilla/StoragePrincipalHelper.h"
#include "mozilla/Telemetry.h"
#include "mozIThirdPartyUtil.h"
#include "nsCRT.h"
#include "nsICookiePermission.h"
#include "nsIConsoleReportCollector.h"
#include "nsIEffectiveTLDService.h"
@ -1180,6 +1181,18 @@ static void RecordPartitionedTelemetry(const CookieStruct& aCookieData,
}
}
bool HasSecurePrefix(const nsCString& aString) {
static const char kSecure[] = "__Secure-";
static constexpr uint32_t kSecureLen = sizeof(kSecure) - 1;
return nsCRT::strncasecmp(aString.get(), kSecure, kSecureLen) == 0;
}
bool HasHostPrefix(const nsCString& aString) {
static const char kHost[] = "__Host-";
static constexpr uint32_t kHostLen = sizeof(kHost) - 1;
return nsCRT::strncasecmp(aString.get(), kHost, kHostLen) == 0;
}
// processes a single cookie, and returns true if there are more cookies
// to be processed
bool CookieService::CanSetCookie(
@ -1290,9 +1303,12 @@ bool CookieService::CanSetCookie(
return newCookie;
}
if (!CheckHiddenPrefix(aCookieData)) {
// If a cookie is nameless, then its value must not start with
// `__Host-` or `__Secure-`
if (aCookieData.name().IsEmpty() && (HasSecurePrefix(aCookieData.value()) ||
HasHostPrefix(aCookieData.value()))) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"failed the CheckHiddenPrefix tests");
"failed hidden prefix tests");
CookieLogging::LogMessageToConsole(
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
"CookieRejectedInvalidPrefix"_ns,
@ -1967,25 +1983,6 @@ bool CookieService::CheckDomain(CookieStruct& aCookieData, nsIURI* aHostURI,
return true;
}
// static
bool CookieService::CheckHiddenPrefix(CookieStruct& aCookieData) {
// If a cookie is nameless, then its value must not start with
// `__Host-` or `__Secure-`
if (!aCookieData.name().IsEmpty()) {
return true;
}
if (StringBeginsWith(aCookieData.value(), "__Host-"_ns)) {
return false;
}
if (StringBeginsWith(aCookieData.value(), "__Secure-"_ns)) {
return false;
}
return true;
}
namespace {
nsAutoCString GetPathFromURI(nsIURI* aHostURI) {
// strip down everything after the last slash to get the path,
@ -2053,13 +2050,8 @@ bool CookieService::CheckPath(CookieStruct& aCookieData,
// regularized and validated the CookieStruct values!
bool CookieService::CheckPrefixes(CookieStruct& aCookieData,
bool aSecureRequest) {
static const char kSecure[] = "__Secure-";
static const char kHost[] = "__Host-";
static const int kSecureLen = sizeof(kSecure) - 1;
static const int kHostLen = sizeof(kHost) - 1;
bool isSecure = strncmp(aCookieData.name().get(), kSecure, kSecureLen) == 0;
bool isHost = strncmp(aCookieData.name().get(), kHost, kHostLen) == 0;
bool isSecure = HasSecurePrefix(aCookieData.name());
bool isHost = HasHostPrefix(aCookieData.name());
if (!isSecure && !isHost) {
// not one of the magic prefixes: carry on

View File

@ -124,7 +124,6 @@ class CookieService final : public nsICookieService,
static bool CheckDomain(CookieStruct& aCookieData, nsIURI* aHostURI,
const nsACString& aBaseDomain,
bool aRequireHostMatch);
static bool CheckHiddenPrefix(CookieStruct& aCookieData);
static bool CheckPath(CookieStruct& aCookieData,
nsIConsoleReportCollector* aCRC, nsIURI* aHostURI);
static bool CheckPrefixes(CookieStruct& aCookieData, bool aSecureRequest);

View File

@ -1,9 +0,0 @@
[__host.document-cookie.html]
[__HoSt: Non-secure origin: 'Path=/;']
expected: FAIL
[__HoSt: Non-secure origin: 'Path=/;domain=web-platform.test']
expected: FAIL
[__HoSt: Non-secure origin: 'Path=/;MaxAge=10']
expected: FAIL

View File

@ -1,15 +0,0 @@
[__host.document-cookie.https.html]
[__HoSt: Secure origin: Does not set 'Path=/;']
expected: FAIL
[__HoSt: Secure origin: Does not set 'Secure; Path=/; Domain=web-platform.test; ']
expected: FAIL
[__HoSt: Secure origin: Does not set 'Path=/;MaxAge=10']
expected: FAIL
[__HoSt: Secure origin: Does not set 'Secure; Path=/; Domain=web-platform.test; MaxAge=10']
expected: FAIL
[__HoSt: Secure origin: Does not set 'Secure; Path=/cookies/resources/list.py']
expected: FAIL

View File

@ -1,14 +1,3 @@
[__host.header.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[__HoSt: Non-secure origin: Does not set 'Path=/;']
expected: FAIL
[__HoSt: Non-secure origin: Does not set 'Path=/;domain=web-platform.test']
expected: FAIL
[__HoSt: Non-secure origin: Does not set 'Path=/;MaxAge=10']
expected: FAIL
[__HoSt: Non-secure origin: Does not set 'Path=/;HttpOnly']
expected: FAIL

View File

@ -1,34 +1,21 @@
[__host.header.https.html]
expected:
if (processor == "x86") and debug: [OK, TIMEOUT]
[__HoSt: Secure origin: Does not set 'Path=/;']
expected: FAIL
[__HoSt: Secure origin: Does not set 'Secure; Path=/; Domain=web-platform.test; ']
expected: FAIL
[__HoSt: Secure origin: Does not set 'Path=/;MaxAge=10']
expected: FAIL
[__HoSt: Secure origin: Does not set 'Secure; Path=/; Domain=web-platform.test; MaxAge=10']
expected:
if (processor == "x86") and debug: [FAIL, NOTRUN]
FAIL
[__HoSt: Secure origin: Does not set 'Path=/;HttpOnly']
expected:
if (processor == "x86") and debug: [FAIL, NOTRUN]
FAIL
[__HoSt: Secure origin: Does not set 'Secure; Path=/; Domain=web-platform.test; HttpOnly']
expected:
if (processor == "x86") and debug: [FAIL, NOTRUN]
FAIL
[__HoSt: Secure origin: Does not set 'Secure; Path=/cookies/resources/list.py']
expected:
if (processor == "x86") and debug: [FAIL, NOTRUN]
FAIL
[__Host: Secure origin: Does not set 'Secure; Path=/; Domain=web-platform.test; MaxAge=10']
expected:

View File

@ -1,11 +1,3 @@
[__secure.document-cookie.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[__SeCuRe: Non-secure origin: Should not set 'Path=/;']
expected: FAIL
[__SeCuRe: Non-secure origin: Should not set 'Path=/;MaxAge=10']
expected: FAIL
[__SeCuRe: Non-secure origin: Should not set 'Path=/;domain=web-platform.test']
expected: FAIL

View File

@ -1,11 +1,3 @@
[__secure.document-cookie.https.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[__SeCuRe: Secure origin: Should not set 'Path=/;']
expected: FAIL
[__SeCuRe: Secure origin: Should not set 'Path=/;MaxAge=10']
expected: FAIL
[__SeCuRe: Secure origin: Should not set 'Path=/;domain=web-platform.test']
expected: FAIL

View File

@ -1,14 +1,3 @@
[__secure.header.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[__SeCuRe: Non-secure origin: Should not set 'Path=/;']
expected: FAIL
[__SeCuRe: Non-secure origin: Should not set 'Path=/;domain=web-platform.test']
expected: FAIL
[__SeCuRe: Non-secure origin: Should not set 'Path=/;MaxAge=10']
expected: FAIL
[__SeCuRe: Non-secure origin: Should not set 'Path=/;HttpOnly']
expected: FAIL

View File

@ -1,15 +1,6 @@
[__secure.header.https.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[__SeCuRe: secure origin: Should not set 'Path=/;']
expected: FAIL
[__SeCuRe: secure origin: Should not set 'Path=/;MaxAge=10']
expected: FAIL
[__SeCuRe: secure origin: Should not set 'Path=/;HttpOnly']
expected: FAIL
[__SeCuRe: secure origin: Should not set 'Path=/;domain=not-web-platform.test']
expected:
if not early_beta_or_earlier: FAIL

View File

@ -1,20 +1,3 @@
[document-cookie.non-secure.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[__SeCuRe: Non-secure origin: 'Path=/;']
expected: FAIL
[__SeCuRe: Non-secure origin: 'Path=/;domain=web-platform.test']
expected: FAIL
[__SeCuRe: Non-secure origin: 'Path=/;MaxAge=10']
expected: FAIL
[__HoSt: Non-secure origin: 'Path=/; ']
expected: FAIL
[__HoSt: Non-secure origin: 'Path=/; domain=web-platform.test']
expected: FAIL
[__HoSt: Non-secure origin: 'Path=/; MaxAge=10']
expected: FAIL