✓ProveIt
Examples / Report #1613943 Saved analysis

CVE-2022-35252: control code in cookie denial of service

curl · 2022-06-269.0s analysis · $0.014 in model calls

What the report claims

An attacker can poison curl's cookie store with cookies containing control characters like form feed, causing Apache to reject subsequent requests with a 400 Bad Request and leading to denial of service.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2022-35252 control code in cookie denial of service

Shown for comparison after analysis. The pipeline did not see this label.

ProveIt's finding

Needs human review

The available evidence does not settle the report. A maintainer should investigate.

Why this finding?
  • The central claim (C1) is that curl lacks validation of control characters when saving cookies. The code that would confirm or contradict this (cookie parsing/storage in lib/cookie.c) is not included in the provided source snippets.
  • The provided source only shows lib/urldata.h and a small part of lib/c-hyper.c, neither of which contains the Set-Cookie parsing logic.
  • The RFC 6265 erratum (E1) confirms the spec excludes control characters from cookie-octet, but does not address Apache's behavior (C4).
  • A human reviewer needs to examine lib/cookie.c (or equivalent) at the target revision to see if cookie name/value validation exists.
What still needs checking
  • The cookie parsing and storage implementation (likely lib/cookie.c) from revision 7230b19a2e17
How this analysis ran 5 claims · 0 citations verified

Checked against curl master on 2022-06-26 (7230b19a2e17). Test evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
grounded
no model · 2 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 2533 tokens · $0.0002
3 · Evidence
3 code snippets
real curl source at 7230b19a2e17 · 3 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
9939 tokens · 6.1s · $0.0136
5 · Receipts
0 of 0 citations verified
every citation must point at code the judge was shown
Review a draft reply to the reporter

Edit and verify before sending.

Thank you for the detailed report. The cookie parsing and storage code (likely in lib/cookie.c) is not included in the source snippets we have for the target revision, so we cannot verify whether curl validates control characters when saving cookies. Could you point to the specific function or file where you believe the validation is missing? That will help us locate the relevant code for assessment.

Inspect all claims and source code 5 claims · 3 code excerpts

Report claims

C1flaw not verifiable

curl does not implement character check on cookie name or value when saving to cookie store

Read the reasoning

The provided source code does not include the cookie parsing and storage logic (typically in lib/cookie.c). The snippets show only lib/urldata.h (CURLcode typedef) and lib/c-hyper.c (a function that calls Curl_http_cookies). The code that would validate or reject control characters when saving cookies is not present, so the claim cannot be verified from the provided code.

C2location not verifiable

cookie store

Read the reasoning

Same as C1: the cookie store implementation is not in the provided source snippets.

C3trigger not verifiable

a form feed character '\f' saved in cookie store

Read the reasoning

The trigger depends on the cookie parsing code accepting a form feed character, which is not in the provided source.

C4impact not verifiable

Apache rejects control characters other than \r or \n in the request head, returning 400 Bad Request

Read the reasoning

This claim is about Apache HTTP server behavior, not curl code. The provided external source (E1) is an RFC 6265 erratum discussing cookie-octet syntax (excluding control characters per the spec), but it does not state that Apache rejects such characters in request headers. No excerpt confirms Apache's behavior.

C5reproduction not verifiable

Save a cookie with form feed using curl -c cookies.txt and then request with that cookie store

Read the reasoning

The reproduction steps depend on the cookie parsing behavior that is not shown in the provided source.

What the report says about other projects

confirmed cookies should not contain control characters per RFC 6265

“cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E ; US-ASCII characters excluding CTLs, ; whitespace DQUOTE, comma, semicolon, ; and backslash” source

not addressed Apache rejects control characters other than \r or \n in the request head

Read the original report (excerpt)

Full report on HackerOne ↗

## Summary: I took a look at https://github.com/curl/curl/pull/9048/commits/d7bcbc7d8d4b6d972d3da12d54819169a19c287b (a sneak peek on a vulnerability to be announced tomorrow). My guess for that vulnerability is that since cookies are persistent, someone who can trick curl into storing cookies can store large amounts of cookies into curl cookie store, which will prevent curl from ever interacting with the server (due to large request being generated causing a 400 error) I found a separate way to do this, curl does not implement character check on cookie name or value when saving to cookie store. So for example a form feed '\f' can be saved in curl's cookie store. When form feed is sent by curl to a server such as Apache, Apache will respond with 400 Error (historically, Apache would accept, however now due to HTTP smuggling concerns, Apache will now strictly reject any such control characters.), preventing someone from ever interacting the server with the cookie store. According to the spec, cookies should not contain control characters anyway, see https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1. ## Steps To Reproduce: 1. In test.php, ````` <?php echo("HTTP/1.1 200 OK\r\nDate: Fri, 29 Apr 2022 10:11:55 GMT\r\nServer: Apache/2.4.43 (Debian)\r\nSet-Cookie: a=b\f; \r\nContent-Length: 0\r\nConnection: close\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n"); ````` Setup malicious server, ````` php test.php | nc -nvlp 3333 ````` 2. Cookie with form feed is saved, see 0c byte before the 0a terminator ````` curl -c cookies.txt http://127.0.0.1:3333 ````` ````` ➜ ~ xxd cookies.txt 00000000: 2320 4e65 7473 6361 7065 2048 5454 5020 # Netscape HTTP 00000010: 436f 6f6b 6965 2046 696c 650a 2320 6874 Cookie File.# ht 00000020: 7470 733a 2f2f 6375 726c 2e73 652f 646f tps://curl.se/do 00000030: 6373 2f68 7474 702d 636f 6f6b 6965 732e cs/http-cookies. 00000040: 6874 6d6c 0a23 2054 6869 7320 6669 6c65 html.# This file 00000050: 2077 6173 2067 656e 6572 6174 6564 2062 was generated b 00000060: 7920 6c69 6263 7572 6c21 2045 6469 7420 y libcurl! Edit 00000070: 6174 2079 6f75 7220 6f77 6e20 7269 736b at your own risk 00000080: 2e0a 0a31 3237 2e30 2e30 2e31 0946 414c ...127.0.0.1.FAL 00000090: 5345 092f 0946 414c 5345 0930 0961 0962 SE./.FALSE.0.a.b 000000a0: 0c0a .. ````` 3. Apache will now respond with "400 ba …

Source code

lib/urldata.hlines 124–192 · definition of CURLcode
124typedef CURLcode (*Curl_datastream)(struct Curl_easy *data,
125 struct connectdata *conn,
126 int *didwhat,
127 bool *done,
128 int select_res);
129#endif
130
131#include "mime.h"
132#include "imap.h"
133#include "pop3.h"
134#include "smtp.h"
135#include "ftp.h"
136#include "file.h"
137#include "vssh/ssh.h"
138#include "http.h"
139#include "rtsp.h"
140#include "smb.h"
141#include "mqtt.h"
142#include "wildcard.h"
143#include "multihandle.h"
144#include "quic.h"
145#include "c-hyper.h"
146
147#ifdef HAVE_GSSAPI
148# ifdef HAVE_GSSGNU
149# include <gss.h>
150# elif defined HAVE_GSSAPI_GSSAPI_H
151# include <gssapi/gssapi.h>
152# else
153# include <gssapi.h>
154# endif
155# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
156# include <gssapi/gssapi_generic.h>
157# endif
158#endif
159
160#ifdef HAVE_LIBSSH2_H
161#include <libssh2.h>
162#include <libssh2_sftp.h>
163#endif /* HAVE_LIBSSH2_H */
164
165#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE
166#define READBUFFER_MAX CURL_MAX_READ_SIZE
167#define READBUFFER_MIN 1024
168
169/* The default upload buffer size, should not be smaller than
170 CURL_MAX_WRITE_SIZE, as it needs to hold a full buffer as could be sent in
171 a write callback.
172
173 The size was 16KB for many years but was bumped to 64KB because it makes
174 libcurl able to do significantly faster uploads in some circumstances. Even
175 larger buffers can help further, but this is deemed a fair memory/speed
176 compromise. */
177#define UPLOADBUFFER_DEFAULT 65536
178#define UPLOADBUFFER_MAX (2*1024*1024)
179#define UPLOADBUFFER_MIN CURL_MAX_WRITE_SIZE
180
181#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
182#define GOOD_EASY_HANDLE(x) \
183 ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
184
185#ifdef HAVE_GSSAPI
186/* Types needed for krb5-ftp connections */
187struct krb5buffer {
188 void *data;
189 size_t size;
190 size_t index;
191 BIT(eof_flag);
192};
lib/urldata.h@curl-7_83_1lines 122–199 · definition of CURLcode as in release curl-7_83_1; differs from master; commits that changed it since: 45de940ceb lib: make more protocol specific struct fields #ifdefed
122typedef CURLcode (*Curl_datastream)(struct Curl_easy *data,
123 struct connectdata *conn,
124 int *didwhat,
125 bool *done,
126 int select_res);
127#endif
128
129#include "mime.h"
130#include "imap.h"
131#include "pop3.h"
132#include "smtp.h"
133#include "ftp.h"
134#include "file.h"
135#include "vssh/ssh.h"
136#include "http.h"
137#include "rtsp.h"
138#include "smb.h"
139#include "mqtt.h"
140#include "wildcard.h"
141#include "multihandle.h"
142#include "quic.h"
143#include "c-hyper.h"
144
145#ifdef HAVE_GSSAPI
146# ifdef HAVE_GSSGNU
147# include <gss.h>
148# elif defined HAVE_GSSAPI_GSSAPI_H
149# include <gssapi/gssapi.h>
150# else
151# include <gssapi.h>
152# endif
153# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
154# include <gssapi/gssapi_generic.h>
155# endif
156#endif
157
158#ifdef HAVE_LIBSSH2_H
159#include <libssh2.h>
160#include <libssh2_sftp.h>
161#endif /* HAVE_LIBSSH2_H */
162
163#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE
164#define READBUFFER_MAX CURL_MAX_READ_SIZE
165#define READBUFFER_MIN 1024
166
167/* The default upload buffer size, should not be smaller than
168 CURL_MAX_WRITE_SIZE, as it needs to hold a full buffer as could be sent in
169 a write callback.
170
171 The size was 16KB for many years but was bumped to 64KB because it makes
172 libcurl able to do significantly faster uploads in some circumstances. Even
173 larger buffers can help further, but this is deemed a fair memory/speed
174 compromise. */
175#define UPLOADBUFFER_DEFAULT 65536
176#define UPLOADBUFFER_MAX (2*1024*1024)
177#define UPLOADBUFFER_MIN CURL_MAX_WRITE_SIZE
178
179#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
180#define GOOD_EASY_HANDLE(x) \
181 ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
182
183/* the type we use for storing a single boolean bit */
184#ifdef _MSC_VER
185typedef bool bit;
186#define BIT(x) bool x
187#else
188typedef unsigned int bit;
189#define BIT(x) bit x:1
190#endif
191
192#ifdef HAVE_GSSAPI
193/* Types needed for krb5-ftp connections */
194struct krb5buffer {
195 void *data;
196 size_t size;
197 size_t index;
198 BIT(eof_flag);
199};
lib/c-hyper.clines 762–775 · definition of cookies
Show 14 lines (not cited by the judge)
762static CURLcode cookies(struct Curl_easy *data,
763 struct connectdata *conn,
764 hyper_headers *headers)
765{
766 struct dynbuf req;
767 CURLcode result;
768 Curl_dyn_init(&req, DYN_HTTP_REQUEST);
769
770 result = Curl_http_cookies(data, conn, &req);
771 if(!result)
772 result = Curl_hyper_header(data, headers, Curl_dyn_ptr(&req));
773 Curl_dyn_free(&req);
774 return result;
775}