curl · Report #4093443
Cookie attribute truncation in curl drops Secure/HttpOnly protections
How it was found
Description:
If a Set-Cookie header contains an = immediately after a semicolon (i.e., ;=), curl stops parsing the attributes and discards everything that follows. This silently drops protections like Secure and HttpOnly, causing curl to later send the cookie over unencrypted HTTP.
Root Cause:
In parse_cookie_header() (lib/cookie.c:614), an = immediately following a ; causes curlx_str_cspn to fail with a zero-length match. This terminates the attribute-parsing loop early, before the Secure attribute is ever evaluated.
Impact: Sensitive cookie data is sent in plaintext over the network (CWE-201).
Steps to Reproduce (PoC):
-
Start a local HTTPS server with a self-signed certificate for the name
cookie.test, and a plain-HTTP server on a second port. The HTTPS one returns this header:Set-Cookie: session=secret;=x; Secure
-
Fetch the HTTPS URL with curl 8.22.0 and save the cookie jar.
--resolvepoints the name at the local server, so no DNS and no public host are needed;-kis only for the self-signed certificate:curl -k -c jar.txt --resolve cookie.test:8443:127.0.0.1 https://cookie.test:8443/
-
Inspect
jar.txt. The fourth tab-separated field is the Secure flag:cookie.test FALSE / FALSE 0 session secret
-
Request the same host name over plaintext HTTP, reusing the jar:
curl -b jar.txt --resolve cookie.test:8080:127.0.0.1 http://cookie.test:8080/
Expected Result:
The Secure attribute is applied, so field 4 of the jar reads TRUE and the
plaintext request in step 4 carries no Cookie: header.
Actual Result: Field 4 reads FALSE and the plaintext server receives the cookie:
GET / HTTP/1.1 Host: cookie.test:8080 User-Agent: curl/8.22.0 Accept: / Cookie: session=secret
Parsing was truncated at the ;= sequence, so Secure was never evaluated.
Reproduction script: one command
python poc.py
{F6928292}
{F6928297}
{F6928301}