✓ProveIt
Examples / Report #2072338 Saved analysis

CVE-2023-38039: HTTP header allocation DOS

curl · 2023-07-1712.0s analysis · $0.012 in model calls

What the report claims

curl does not limit the amount of HTTP headers it receives, allowing a malicious server to cause resource exhaustion via continuous header parsing.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2023-38039 HTTP headers eat all memory

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 core claim (C1, C2) requires examining lib/transfer.c header parsing logic, which is not provided in the source code excerpt (only lib/optiontable.pl is shown).
  • The attack vector (C3) is plausible and demonstrated by the reporter's server code.
  • External sources confirm servers and some HTTP clients enforce header limits, but do not address curl's behavior.
  • Without the actual header handling code, it cannot be determined if curl lacks a header count/size limit or if the reported DoS is feasible.
What still needs checking
  • lib/transfer.c source code (especially header parsing functions around line 420 and the main HTTP response reading loop)
  • Any existing header count or size limits in curl's HTTP parsing (e.g., MAX_HTTP_HEADERS, header size caps, or streaming processing that avoids accumulation)
How this analysis ran 5 claims · 0 citations verified

Checked against curl master on 2023-07-17 (ebd83bfbae31). 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
partially grounded
no model · 2 references checked out, 2 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 1573 tokens · $0.0002
3 · Evidence
1 code snippets
real curl source at ebd83bfbae31 · 3 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
6552 tokens · 9.9s · $0.0122
5 · Receipts
0 of 1 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 and exploit code. To assess this, we need to review curl's HTTP header parsing implementation in lib/transfer.c (the file referenced at line 420). That file was not included in the code provided for triage. Could you point to the specific function(s) that read and store response headers, or confirm whether curl currently enforces any limit on the number or total size of headers? This will let us determine if the unbounded allocation you describe exists in the code.

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

Report claims

C1flaw not verifiable

curl does not limit the amount of HTTP headers to be received

Read the reasoning

The claim that curl does not limit HTTP headers requires examining the header parsing code in lib/transfer.c, which is not provided in the source code section. Only lib/optiontable.pl (a Perl build script) is shown. Without the actual header handling logic, this claim cannot be verified or contradicted.

C2location not verifiable

vulnerable function located at https://github.com/curl/curl/blob/master/lib/transfer.c#L420

Read the reasoning

The report points to lib/transfer.c#L420 as the vulnerable function, but this file is not included in the provided curl source code. The deterministic checks confirm the revision (ebd83bfbae31) but the source excerpt is unrelated. Cannot verify the location or the function's behavior.

C3trigger supported

malicious HTTP server continuously sends new headers and keeps the socket open

Read the reasoning

The attack trigger is described by the reporter's own server code (exploit.c), which is provided in the report. The code shows an infinite loop sending header lines while keeping the socket open. This claim is about the attacker's behavior, not curl's code, and is supported by the included exploit snippet.

report:0
C4impact not verifiable

user's machine allocates more and more resources until the system is eventually exhausted

Read the reasoning

The claimed impact (resource exhaustion) depends on curl's header parsing allocating unbounded memory. Without lib/transfer.c or the header parsing implementation, it cannot be determined whether curl actually accumulates headers without limit or has mitigations (e.g., max header count, size limits, or streaming processing).

C5reproduction not verifiable

compile exploit.c and execute the server binary, then run `curl 127.0.0.1:80`

Read the reasoning

Reproduction steps rely on the attacker's exploit.c (provided in report) and running curl against it. Whether this reproduces a curl vulnerability depends on curl's actual header handling code, which is not provided. The steps themselves are clear but their effectiveness cannot be assessed.

Deterministic checks that failed

  • symbol send_payload() does not exist in curl at ebd83bfbae31 or in any release since 7.50
  • quote only 0/6 quoted lines appear anywhere in curl at ebd83bfbae31

What the report says about other projects

not addressed modern browsers abort the connection once they reach a threshold

confirmed IIS, Apache, Nginx, Tomcat limit header size and return 413/431 errors

“HTTP does not define any restrictions. But most web servers do limit the size of the headers they accept. [...] IIS - 8K-16K (varies by version) Apache - 8K Nginx - 4K-8K Tomcat - 8K – 48K If the header size exceeds this limit, the server will return a 413 Entity Too Large error.” source

confirmed Apache HttpClient has maxHeaderCount setting for maximum HTTP header count

“Determines the maximum HTTP header count allowed. If set to a positive value, the number of HTTP headers received from the data stream exceeding this limit” source

Read the original report

Full report on HackerOne ↗

It was found that curl does not currently limit the amount of HTTP headers to be received leading to a potential DOS for the users. If an attacker sets up a malicious HTTP server that continuously sends new headers and keeps the socket open, curl will continuously listen on the socket and parse new received headers. This leads to the user's machine allocating more and more resources until the system is eventually exhausted. From research the vulnerable function seems to be located at https://github.com/curl/curl/blob/master/lib/transfer.c#L420. For comparison, modern browsers abort the connection once they reach a threshold. One potential fix to not affect functionality too much would be to set an arbitrary limit to the amount of headers to receive, which I believe is the solution adapted by most modern browsers to solve this issue. ## Screenshot {F2513231} My excuses for the French in screenshot (I'm sorting programs by RAM usage, and the top one is of course the windows terminal from which I executed curl). On there you can see my user terminal (windows) launching `curl 127.0.0.1:80` to the left, on the right we see the attacker's server (attaching full source code to this report). Throughout testing memory usage kept increasing alarmingly high. ## Malicious server code extract: ``` void send_payload(int fd) { memset(speedup, 'a', sizeof(speedup)); //first we send the start of a valid HTTP request with status line and a few headers send(fd, validreq, sizeof(validreq), MSG_MORE); while (1337) { //this is used to speed up the dos process sending extra bytes send(fd, speedup, sizeof(speedup), MSG_MORE ); //now we're spamming the curl client with the header "a:b" then telling it there's more to come ! send(fd, "a:b\x0d\x0a", 5, MSG_MORE ); } } ``` ## Steps To Reproduce: 1. Compile exploit.c and execute the server binary. Note: depending on your system, feel free to play with the `ATTACK_SPEED` define of the code, to speed up testing. 2. Open up another terminal and as the victim try `curl 127.0.0.1:80` 3. Observe system metrics. ## Impact DOS/overloading of user's system through malicious HTTP server interaction with curl's header parsing.

Source code

lib/optiontable.pllines 74–115 · definition of while
74while(<STDIN>) {
75 my $l = $_;
76 if($fl) {
77 # continued deprecation
78 if($l =~ /(.*)\),/) {
79 $fl .= $1;
80
81 # the end
82 my @p=split(/, */, $fl);
83 add($p[0], $p[1], $p[2]);
84 undef $fl;
85 }
86 else {
87 # another line to append
88 chomp $l;
89 $fl .= $l;
90 }
91 }
92
93 if(/^ *CURLOPTDEPRECATED\((.*)/) {
94 $fl = $1;
95 chomp $fl;
96 }
97
98 if(/^ *CURLOPT\(([^,]*), ([^,]*), (\d+)\)/) {
99 my($opt, $type, $num)=($1,$2,$3);
100 add($opt, $type, $num);
101 }
102
103 # alias for an older option
104 # old = new
105 if(/^#define (CURLOPT_[^ ]*) *(CURLOPT_\S*)/) {
106 my ($o, $n)=($1, $2);
107 # skip obsolete ones
108 if($n !~ /OBSOLETE/) {
109 $o =~ s/^CURLOPT_//;
110 $n =~ s/^CURLOPT_//;
111 $alias{$o} = $n;
112 push @names, $o,
113 }
114 }
115}