CVE-2026-80255: Verified Reproduction
CVE-2026-80255: curl: Secure cookie attribute bypass when a TAB character precedes the Secure attribute in Set-Cookie
CVE-2026-80255 is verified against curl/curl · github. Affected versions: curl 8.13.0 through 8.21.0 inclusive; the machine-readable advisory lists 8.13.0, 8.14.0, 8.14.1, 8.15.0, 8.16.0, 8.17.0, 8.18.0, 8.19.0, 8.20.0, and 8.21.0. Fixed in curl 8.22.0. This low reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00347.
What Is CVE-2026-80255?
CVE-2026-80255 is a low-severity vulnerability affecting curl/curl curl 8.13.0 through 8.21.0 inclusive; the machine-readable advisory lists 8.13.0, 8.14.0, 8.14.1, 8.15.0, 8.16.0, 8.17.0, 8.18.0, 8.19.0, 8.20.0, and 8.21.0.. Pruva has independently reproduced it and publishes a verified, runnable proof-of-concept (reproduction REPRO-2026-00347).
CVE-2026-80255 Severity
CVE-2026-80255 is rated low severity.
Low — limited impact or hard to exploit. Address in the normal cycle.
Affected curl/curl Versions
curl/curl · github versions curl 8.13.0 through 8.21.0 inclusive; the machine-readable advisory lists 8.13.0, 8.14.0, 8.14.1, 8.15.0, 8.16.0, 8.17.0, 8.18.0, 8.19.0, 8.20.0, and 8.21.0. are affected.
How to Reproduce CVE-2026-80255
pruva-verify REPRO-2026-00347 curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00347/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-80255
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
HTTPS Set-Cookie response header containing the literal bytes `sess=SECRET;\x09Secure`
- HTTPS TCP response
- real curl CLI/libcurl cookie parser
- cookie jar
- plaintext HTTP TCP request to the same non-localhost host
How the agent worked
Root Cause and Exploit Chain for CVE-2026-80255
CVE-2026-80255 is a curl/libcurl HTTP cookie-parser vulnerability in which a response attribute encoded as ;\tSecure is not recognized as the Secure attribute. In the tested vulnerable fix parent, curl persisted sess=SECRET with its secure-only field set to FALSE; a later invocation of the real curl command-line product then transmitted Cookie: sess=SECRET to a plaintext HTTP peer. The exact fixed commit persisted the same cookie with Secure=TRUE and omitted it from the equivalent plaintext request.
- Package/component affected: curl/libcurl, specifically
lib/cookie.cHTTPSet-Cookieparsing as exercised by the curl command-line product. - Affected versions: The advisory reports curl 8.13.0 through 8.21.0, introduced by
1aea05a6c2699e80c75936d5. Per the fixed-commit checkout rule, this run tested the exact fix parent621e507300e6c83966567b6ae0352ca82544df13as vulnerable and4f6aa41a0145e930e766775dbe860883d350aa0aas fixed. - Risk level and consequences: Low severity, but with a concrete confidentiality consequence. A server capable of returning the crafted
Set-Cookieheader can cause affected curl clients to disclose a cookie intended for encrypted transport in a later plaintext HTTP request to the same non-localhost origin. The cookie is visible to that HTTP peer and to network observers on the plaintext path.
Impact Parity
- Disclosed/claimed maximum impact: Information disclosure of a cookie intended to have the
Securetransport restriction. - Reproduced impact from this run: The literal secret
sess=SECRETwas captured in plaintext HTTP request bytes in two independent vulnerable product attempts after being set through two independent HTTPS TCP sessions. - Parity:
full - Not demonstrated: No higher impact such as arbitrary memory disclosure or code execution was claimed or attempted. The demonstrated disclosure is bounded to the affected application's cookie data and workflow.
Root Cause
The parser in the vulnerable commit scans each cookie attribute name with:
if(!curlx_str_cspn(&ptr, &name, ";\t\r\n=")) {
Including horizontal TAB in this delimiter set makes parsing of Set-Cookie: sess=SECRET;\tSecure terminate in a way that prevents the following token from matching the recognized Secure attribute. curl therefore persists the cookie with the secure field set to FALSE. When that cookie jar is loaded for a later request to plaintext http://tab-cookie.invalid, curl considers it eligible and emits the secret in the Cookie request header.
Fix commit 4f6aa41a0145e930e766775dbe860883d350aa0a changes the scan delimiter to:
if(!curlx_str_cspn(&ptr, &name, ";\r\n=")) {
TAB is then handled as leading whitespace around the attribute name, allowing Secure to be recognized. The fixed cookie jar records TRUE, and curl omits the cookie from plaintext HTTP. The fix also adds upstream regression test 2885 for this exact TAB-before-Secure form.
Reproduction Steps
- Run
bundle/repro/reproduction_steps.shfrom any directory; it derives portable paths from its own location and honorsPRUVA_ROOT. - The script reads
bundle/project_cache_context.json, uses the required prepared repository path when available, resolves fixed commit4f6aa41a0145e930e766775dbe860883d350aa0aand its first parent, and verifies the vulnerable and fixed source hunks before building non-sanitized real curl command-line products. - For each isolated attempt, it starts an HTTPS TCP peer, maps the non-localhost name
tab-cookie.invalidto that peer with curl--resolve, and sends the literal wire headerSet-Cookie: sess=SECRET;\x09Secure. It then starts a fresh plaintext HTTP peer, loads the resulting cookie jar with the same product build, and captures the request bytes. - It requires two vulnerable attempts to show
secure=FALSEplus a captured plaintextCookie: sess=SECRET, and two fixed attempts to showsecure=TRUEwith no Cookie header. All curl invocations are bounded bytimeout. - On success it writes strict, target-bound
bundle/repro/runtime_manifest.jsonwith SHA-256 hashes of finalized evidence files. Exit status 0 means the issue was confirmed; status 1 means the required divergence was not reproduced.
Expected terminal output includes:
PASS vulnerable attempt 1: secure=FALSE plaintext_cookie_seen=true
PASS vulnerable attempt 2: secure=FALSE plaintext_cookie_seen=true
PASS fixed attempt 1: secure=TRUE plaintext_cookie_seen=false
PASS fixed attempt 2: secure=TRUE plaintext_cookie_seen=false
CONFIRMED: vulnerable curl disclosed sess=SECRET over plaintext HTTP in two attempts; fixed curl blocked it in two attempts.
Evidence
bundle/repro/vulnerable-attempt-1.log— vulnerable transcript, SHA-256e995fcb7f7e5422788e3fc188312333fc71aa3bfd1b01c9d57d0586a9bfdfafd.bundle/repro/vulnerable-attempt-2.log— second vulnerable transcript, SHA-256ba0967b31d8a4e8657df1bdb6b7fd788529a2524cb3d7cba0f5c2865a681edc8.bundle/repro/fixed-attempt-1.log— fixed negative control, SHA-256b30e5a532dc4390fb7b122b44d2a5aba4128e46a457e5e8870601f34a3ba6b29.bundle/repro/fixed-attempt-2.log— second fixed negative control, SHA-256c5afc0185862af91e1b0f899fcdea3cb4098635dae13fe95a886509477807201.bundle/repro/target-identity.log— exact commits, patch lines, binary hashes, and product versions, SHA-2569b2d64973b3600d6852c952279942e6e51c36e7a84f71e7a88f18269658c8488.bundle/repro/runtime_manifest.json— entrypoint state, vulnerable source identity, proof artifact list, and checked hashes.bundle/logs/reproduction_steps.log— overall diagnostics (not hashed as immutable proof because shell-wideteewrites it through script exit).bundle/logs/cmake-vulnerable.log,build-vulnerable.log,cmake-fixed.log, andbuild-fixed.log— build diagnostics.
The critical vulnerable excerpt is:
COMMIT=621e507300e6c83966567b6ae0352ca82544df13
ATTACKER_HEADER_HEX=5365742d436f6f6b69653a20736573733d5345435245543b09536563757265
COOKIE_JAR_SECURE_FIELD=FALSE
PLAINTEXT_COOKIE_HEADER_SEEN=true
...
Host: tab-cookie.invalid:<dynamic-port>
Cookie: sess=SECRET
The fixed negative control contains:
COMMIT=4f6aa41a0145e930e766775dbe860883d350aa0a
COOKIE_JAR_SECURE_FIELD=TRUE
PLAINTEXT_COOKIE_HEADER_SEEN=false
Its captured plaintext request ends after Accept: */* and contains no Cookie header. Both peer transcripts record LISTENING, ACCEPTED, protocol request bytes, and the exact malicious header bytes. The tested environment was Linux x86-64, curl/libcurl 8.22.0-DEV at the exact commits, OpenSSL 3.5.5, and nghttp2 1.68.0. The target digest is SHA-256 of git:https://github.com/curl/curl@621e507300e6c83966567b6ae0352ca82544df13: 99769c35eb8a8ef5d8c6f984733cb9a16c536698292048e4b4ef2b6fe755f495.
Recommendations / Next Steps
- Upgrade to curl 8.22.0 or later, or apply the complete change from fixed commit
4f6aa41a0145e930e766775dbe860883d350aa0ato affected downstream branches. - Do not treat TAB as a terminal name delimiter before cookie attribute matching; trim accepted optional whitespace and then compare the complete attribute token.
- Preserve an end-to-end regression test with the literal
0x09byte beforeSecure, a non-localhost origin, a persisted cookie jar, and a later plaintext HTTP request. Testing only the jar is weaker than proving that the secret is not emitted. - Include both a vulnerable regression fixture and a fixed negative control to avoid false conclusions caused by curl's special secure-cookie treatment of localhost/loopback origins.
Additional Notes
- Idempotency confirmation: The final script completed successfully twice consecutively. Each execution itself performed two clean vulnerable attempts and two clean fixed attempts.
- Real boundary: The primary proof invokes the real curl command-line product. Attacker input crosses accepted HTTPS TCP connections, and disclosure crosses separate plaintext HTTP TCP connections; the vulnerable parser is not called directly by a unit harness.
- Sanitizers: None were used. This is a protocol/confidentiality defect rather than a memory-safety crash.
- Edge case avoided: The peer listens on loopback for containment, but requests use
tab-cookie.invalidvia--resolve. Using127.0.0.1as the URL host would be an invalid negative control because curl intentionally permits Secure cookies in localhost-like contexts. - Version string nuance: The exact fix parent and fix commit both report the development version string
8.22.0-DEV; commit hashes and binary SHA-256 values, not that mutable prose label, bind the two tested builds.
CVE-2026-80255 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
# Root Cause Analysis: CVE-2026-80255 ## Summary CVE-2026-80255 is a curl/libcurl cookie-parser bug in which an HTTP `Set-Cookie` response attribute written as `;\tSecure` is not recognized as the `Secure` attribute. On affected releases, curl can persist the cookie without its secure-only restriction and later disclose its value in a plaintext HTTP request to the same host. This report is initialized from the accepted claim and will be finalized against fresh vulnerable/fixed runtime evidence produced by `bundle/repro/reproduction_steps.sh`. ## Impact - **Affected component:** curl/libcurl HTTP cookie parser. - **Affected versions:** Reported as curl 8.13.0 through 8.21.0; the bug was introduced by commit `1aea05a6c2699e80c75936d5` and fixed for curl 8.22.0. - **Risk and consequences:** Low-severity confidentiality failure. A remote HTTP peer that can set a cookie may cause an affected curl client to omit the cookie's Secure flag and subsequently transmit the cookie over plaintext HTTP, exposing secret cookie data to the plaintext endpoint and network observers. ## Impact Parity - **Disclosed/claimed maximum impact:** Information disclosure of a cookie intended to be restric… [truncated]
Artifacts and Evidence for CVE-2026-80255
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-80255
Upgrade curl/curl · github to curl 8.22.0 or later.
FAQ: CVE-2026-80255
Is CVE-2026-80255 exploitable?
How severe is CVE-2026-80255?
What type of vulnerability is CVE-2026-80255?
Which versions of curl/curl are affected by CVE-2026-80255?
Is there a fix for CVE-2026-80255?
How can I reproduce CVE-2026-80255?
Is the CVE-2026-80255 reproduction verified?
References for CVE-2026-80255
Authoritative sources for CVE-2026-80255 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.