From e66b81a53283100b0d53c840844d3865b3eba951 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 8 Jun 2026 16:37:44 +0200 Subject: [PATCH] cookie: tailmatch the domains for secure override If a SECURE cookie is set for a sub-domain (`example.com`) and is then attempted to get set again for more specific part of that domain (`www.example.com`) without the SECURE property, the second occurance should not be allowed. Reported-by: Trail of Bits Verified by test 3305 Closes #21910 --- lib/cookie.c | 6 ++- tests/data/Makefile.am | 2 +- tests/data/test3305 | 84 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 tests/data/test3305 diff --git a/lib/cookie.c b/lib/cookie.c index b288a2c1d0..e6b6e4f132 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -863,8 +863,10 @@ static bool replace_existing(struct Curl_easy *data, bool matching_domains = FALSE; if(clist->domain && co->domain) { - if(curl_strequal(clist->domain, co->domain)) - /* The domains are identical */ + if(cookie_tailmatch(clist->domain, strlen(clist->domain), + co->domain) || + cookie_tailmatch(co->domain, strlen(co->domain), clist->domain)) + /* The existing one is a tail of the new or vice versa */ matching_domains = TRUE; } else if(!clist->domain && !co->domain) diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index b0caa11346..393f7531bd 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -283,7 +283,7 @@ test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 \ test3208 test3209 test3210 test3211 test3212 test3213 test3214 test3215 \ test3216 test3217 test3218 test3219 test3220 test3221 \ \ -test3300 test3301 test3302 test3303 test3304 \ +test3300 test3301 test3302 test3303 test3304 test3305 \ \ test3400 \ \ diff --git a/tests/data/test3305 b/tests/data/test3305 new file mode 100644 index 0000000000..7a6d63beee --- /dev/null +++ b/tests/data/test3305 @@ -0,0 +1,84 @@ + + + + +HTTP +cookies +--resolve + + + +# Server-side + + +HTTP/1.1 301 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 6 +Set-Cookie: this=secret; domain=example.com; secure; path=/ +Set-Cookie: that=secret; domain=www.example.com; secure; path=/ +Set-Cookie: second=fine; + +-foo- + + +# The cookie 'this' should not be accepted since it would be the same as already +# set with a 'secure' flag. +# The cookie 'second' is however not secure so it is fair game to override + +HTTP/1.1 301 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 6 +Set-Cookie: this=open; path=/ +Set-Cookie: that=open; path=/; domain=example.com +Set-Cookie: second=override + +-foo- + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 6 + +-foo- + + + +# Client-side + + +http +https + + +same-name cookie over HTTPS and HTTP with different domains + + +https://www.example.com:%HTTPSPORT/ http://www.example.com:%HTTPPORT/%TESTNUMBER0002 https://www.example.com:%HTTPSPORT/%TESTNUMBER0003 --insecure -c %LOGDIR/cookie%TESTNUMBER --resolve www.example.com:%HTTPSPORT:%HOSTIP --resolve www.example.com:%HTTPPORT:%HOSTIP + + + +# Verify data after the test has been "shot" + + +GET / HTTP/1.1 +Host: www.example.com:%HTTPSPORT +User-Agent: curl/%VERSION +Accept: */* + +GET /%TESTNUMBER0002 HTTP/1.1 +Host: www.example.com:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* +Cookie: second=fine + +GET /%TESTNUMBER0003 HTTP/1.1 +Host: www.example.com:%HTTPSPORT +User-Agent: curl/%VERSION +Accept: */* +Cookie: second=override; that=secret; this=secret + + + +