← Commit list

95c1e8915d

Daniel Stenberg
Daniel Stenberg
2026-08-29
SUCCESS Duration: 417s

Subject

cookie: cookies set for an exact PSL domain is host-only

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/cookie.c+11 -4
@@ -798,7 +798,7 @@ static CURLcode parse_netscape(struct Cookie *co,
}
static bool is_public_suffix(struct Curl_easy *data,
- const struct Cookie *co,
+ struct Cookie *co,
const char *domain)
{
#ifdef USE_LIBPSL
@@ -838,6 +838,13 @@ static bool is_public_suffix(struct Curl_easy *data,
Curl_strntolower(lcase, domain, dlen);
lcase[dlen] = 0;
acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie);
+
+ /* if the cookie is acceptable, but is set for a PSL domain, then it
+ cannot be tailmatching */
+ if(acceptable && co->tailmatch &&
+ curl_strequal(co->domain, domain) &&
+ psl_is_public_suffix(psl, lcookie))
+ co->tailmatch = FALSE;
}
else {
/* libpsl says localhost is a PSL, we think not */
@@ -1023,6 +1030,9 @@ CURLcode Curl_cookie_add(struct Curl_easy *data,
/* The __Secure- prefix only requires that the cookie be set secure */
goto fail;
+ if(!(flags & COOKIE_NOPSL) && is_public_suffix(data, co, domain))
+ goto fail;
+
if(co->prefix_host) {
/*
* The __Host- prefix requires the cookie to be secure, have a "/" path
@@ -1046,9 +1056,6 @@ CURLcode Curl_cookie_add(struct Curl_easy *data,
if(!(flags & COOKIE_NOEXPIRE))
remove_expired(ci);
- if(!(flags & COOKIE_NOPSL) && is_public_suffix(data, co, domain))
- goto fail;
-
/*
* Now we have parsed the incoming line, we must now check if this supersedes
* an already existing cookie, which it may if the previous have the same
tests/data/Makefile.am+1 -0
@@ -1940,6 +1940,7 @@ TESTCASES = \
test2309 \
test2310 \
test2311 \
+ test2318 \
test2349 \
\
test2397 \
tests/data/test1136+1 -1
@@ -59,7 +59,7 @@ http://www.example.ck/%TESTNUMBER http://www.ck/%TESTNUMBER http://z-1.compute-1
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-.z-1.compute-1.amazonaws.com TRUE / FALSE 0 test5 forbidden5
+z-1.compute-1.amazonaws.com FALSE / FALSE 0 test5 forbidden5
.www.ck TRUE / FALSE 0 test4 allowed4
.www.example.ck TRUE / FALSE 0 test2 allowed2
</file>
tests/data/test2318+65 -0
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+cookies
+</keywords>
+</info>
+
+<reply>
+<data crlf="headers">
+HTTP/1.1 200 OK
+Content-Length: 6
+Set-Cookie: sid=DOMAIN_SECRET; Domain=github.io; Path=/
+
+-foo-
+</data>
+
+<data2 crlf="headers">
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/html
+
+-foo-
+</data2>
+</reply>
+
+# Client-side
+<client>
+<features>
+PSL
+cookies
+</features>
+<server>
+http
+</server>
+<name>
+Get cookies from PSL domain then use *.domain
+</name>
+<command>
+--resolve github.io:%HTTPPORT:%HOSTIP --resolve attacker.github.io:%HTTPPORT:%HOSTIP -b "" http://github.io:%HTTPPORT/%TESTNUMBER http://attacker.github.io:%HTTPPORT/%TESTNUMBER0002 http://github.io:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="headers">
+GET /%TESTNUMBER HTTP/1.1
+Host: github.io:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+GET /%TESTNUMBER0002 HTTP/1.1
+Host: attacker.github.io:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+GET /%TESTNUMBER HTTP/1.1
+Host: github.io:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+Cookie: sid=DOMAIN_SECRET
+
+</protocol>
+</verify>
+</testcase>
tests/data/test798+2 -1
@@ -39,6 +39,7 @@ HTTP cookies in a folded header
-4 http://localhost:%HTTPPORT/we/want/%TESTNUMBER -b none -c %LOGDIR/jar%TESTNUMBER.txt
</command>
<features>
+PSL
cookies
local-http
</features>
@@ -58,7 +59,7 @@ Accept: */*
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-#HttpOnly_.localhost TRUE /p4 TRUE 0 flavor tasty
+#HttpOnly_localhost FALSE /p4 TRUE 0 flavor tasty
</file>
</verify>
</testcase>