Firefox · Networking
CVE-2026-6768
Logic Error in Networking
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
fornetwerk/cookie/CookiePrefixes.cpp |
modified |
Files Changed
netwerk/cookie/CookiePrefixes.cpptesting/web-platform/meta/cookies/prefix/__Host-Http.https.html.ini
Patch
diff --git a/netwerk/cookie/CookiePrefixes.cpp b/netwerk/cookie/CookiePrefixes.cpp
index 6086cb6e715..4f451abad04 100644
--- a/netwerk/cookie/CookiePrefixes.cpp
+++ b/netwerk/cookie/CookiePrefixes.cpp
@@ -15,19 +15,28 @@ struct CookiePrefix {
std::function<bool(const CookieStruct&, bool)> mCallback;
};
+// Ordered longest-prefix-first so that more specific prefixes (e.g.
+// __Host-Http-) are checked before shorter prefixes they start with (e.g.
+// __Host-), since Check() returns on the first match.
+//
+// Per RFC 6265bis §5.4, UAs MUST match these prefixes case-insensitively
+// (see Check() below), even though §4.1.3 describes them with "case-sensitive
+// match" language — that wording applies to server-side semantics, not UA
+// enforcement.
MOZ_RUNINIT CookiePrefix gCookiePrefixes[] = {
- {CookiePrefixes::eSecure, "__Secure-"_ns, u"__Secure-"_ns,
+ {CookiePrefixes::eHostHttp, "__Host-Http-"_ns, u"__Host-Http-"_ns,
[](const CookieStruct& aCookieData, bool aSecureRequest) -> bool {
- // If a cookie's name begins with a case-sensitive match for the string
- // __Secure-, then the cookie will have been set with a Secure attribute.
- return aSecureRequest && aCookieData.isSecure();
+ // RFC 6265bis §4.1.3: the __Host-Http- prefix requires Secure,
+ // HttpOnly, Path=/, and no Domain attribute.
+ return aSecureRequest && aCookieData.isSecure() &&
+ aCookieData.isHttpOnly() && aCookieData.host()[0] != '.' &&
+ aCookieData.path().EqualsLiteral("/");
}},
{CookiePrefixes::eHost, "__Host-"_ns, u"__Host-"_ns,
[](const CookieStruct& aCookieData, bool aSecureRequest) -> bool {
- // If a cookie's name begins with a case-sensitive match for the string
- // __Host-, then the cookie will have been set with a Secure attribute, a
- // Path attribute with a value of /, and no Domain attribute.
+ // RFC 6265bis §4.1.3: the __Host- prefix requires Secure, Path=/,
+ // and no Domain attribute.
return aSecureRequest && aCookieData.isSecure() &&
aCookieData.host()[0] != '.' &&
aCookieData.path().EqualsLiteral("/");
@@ -35,22 +44,15 @@ MOZ_RUNINIT CookiePrefix gCookiePrefixes[] = {
{CookiePrefixes::eHttp, "__Http-"_ns, u"__Http-"_ns,
[](const CookieStruct& aCookieData, bool aSecureRequest) -> bool {
- // If a cookie's name begins with a case-sensitive match for the string
- // __Http-, then the cookie will have been set with a Secure attribute,
- // and an HttpOnly attribute.
+ // RFC 6265bis §4.1.3: the __Http- prefix requires Secure and HttpOnly.
return aSecureRequest && aCookieData.isSecure() &&
aCookieData.isHttpOnly();
}},
- {CookiePrefixes::eHostHttp, "__Host-Http-"_ns, u"__Host-Http-"_ns,
+ {CookiePrefixes::eSecure, "__Secure-"_ns, u"__Secure-"_ns,
[](const CookieStruct& aCookieData, bool aSecureRequest) -> bool {
- // If a cookie's name begins with a case-sensitive match for the string
- // __Host-Http-, then the cookie will have been set with a Secure
- // attribute, an HttpOnly attribute, a Path attribute with a value of /,
- // and no Domain attribute.
- return aSecureRequest && aCookieData.isSecure() &&
- aCookieData.isHttpOnly() && aCookieData.host()[0] != '.' &&
- aCookieData.path().EqualsLiteral("/");
+ // RFC 6265bis §4.1.3: the __Secure- prefix requires Secure.
+ return aSecureRequest && aCookieData.isSecure();
}},
};
@@ -83,6 +85,9 @@ bool CookiePrefixes::Has(const nsACString& aString) {
// static
bool CookiePrefixes::Check(const CookieStruct& aCookieData,
bool aSecureRequest) {
+ // RFC 6265bis §5.4 requires UAs to match prefixes case-insensitively.
+ // This prevents servers that process cookie names case-insensitively from
+ // inadvertently accepting miscapitalized prefixes without their guarantees.
for (CookiePrefix& prefix : gCookiePrefixes) {
if (StringBeginsWith(aCookieData.name(), prefix.mPrefixCString,
nsCaseInsensitiveCStringComparator)) {
diff --git a/testing/web-platform/meta/cookies/prefix/__Host-Http.https.html.ini b/testing/web-platform/meta/cookies/prefix/__Host-Http.https.html.ini
deleted file mode 100644
index 87e1e3b10da..00000000000
--- a/testing/web-platform/meta/cookies/prefix/__Host-Http.https.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[__Host-Http.https.html]
- [__Host-Http: Does not set via DOM 'Secure; Path=/']
- expected: FAIL
-
- [__Host-Http: Does not set via HTTP with 'Secure; Path=/']
- expected: FAIL
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/testing/web-platform/meta/cookies/prefix/__Host-Http.https.html.ini b/testing/web-platform/meta/cookies/prefix/__Host-Http.https.html.ini deleted file mode 100644 index 87e1e3b10da..00000000000 --- a/testing/web-platform/meta/cookies/prefix/__Host-Http.https.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[__Host-Http.https.html] - [__Host-Http: Does not set via DOM 'Secure; Path=/'] - expected: FAIL - - [__Host-Http: Does not set via HTTP with 'Secure; Path=/'] - expected: FAIL
Loading diff…
References
On This Page