]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
headers: enforce a max number of response header to accept
authorDaniel Stenberg <daniel@haxx.se>
Wed, 7 May 2025 22:21:26 +0000 (00:21 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 8 May 2025 06:17:56 +0000 (08:17 +0200)
The limit is 5000 headers in a single transfer. To avoid problems caused
by mistakes or malice.

Add test 747 to verify

Reported-by: wolfsage on hackerone
Closes #17281

lib/headers.c
lib/http.h
tests/data/Makefile.am
tests/data/test498
tests/data/test747 [new file with mode: 0644]

index c1ff58c931e969fe675ef074c203264718ad8981..9f522ecc1318dba818316698f8ff239741443371 100644 (file)
@@ -313,6 +313,11 @@ CURLcode Curl_headers_push(struct Curl_easy *data, const char *header,
         return CURLE_WEIRD_SERVER_REPLY;
     }
   }
+  if(Curl_llist_count(&data->state.httphdrs) >= MAX_HTTP_RESP_HEADER_COUNT) {
+    failf(data, "Too many response headers, %d is max",
+          MAX_HTTP_RESP_HEADER_COUNT);
+    return CURLE_TOO_LARGE;
+  }
 
   hs = calloc(1, sizeof(*hs) + hlen);
   if(!hs)
index ba7a121d094f56cdfb28c412cf866228fa06d19f..8876f380447bc6e70b771125cbac450c660af09e 100644 (file)
@@ -174,6 +174,10 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
    version. This count includes CONNECT response headers. */
 #define MAX_HTTP_RESP_HEADER_SIZE (300*1024)
 
+/* MAX_HTTP_RESP_HEADER_COUNT is the maximum number of response headers that
+   libcurl allows for a single HTTP response, including CONNECT and
+   redirects. */
+#define MAX_HTTP_RESP_HEADER_COUNT 5000
 
 #endif /* CURL_DISABLE_HTTP */
 
index cf372baa41a523cca569f46f86dd088da50cf0db..e3571be5579bd40c4df1ac694a4c9c3f7f409460 100644 (file)
@@ -107,7 +107,7 @@ test709 test710 test711 test712 test713 test714 test715 test716 test717 \
 test718 test719 test720 test721 test722 test723 test724 test725 test726 \
 test727 test728 test729 test730 test731 test732 test733 test734 test735 \
 test736 test737 test738 test739 test740 test741 test742 test743 test744 \
-test745 test746 \
+test745 test746 test747 \
 \
 test780 test781 test782 test783 test784 test785 test786 test787 test788 \
 test789 test790 test791 \
index 6d9454c066a2639874a53d59b037821a93f1f6b1..6c9f8d239e0ba7371a2713b49451e59db2dde34d 100644 (file)
@@ -20,7 +20,7 @@ Content-Length: 6
 Location: /
 Connection: close
 Content-Type: text/html
-%repeat[1700 x Repeat-this-Header-a-large-number-of-times: Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry, who was a farmer, and Aunt Em, who was the farmer’s wife.%0a]%
+%repeat[1700 x Repeat-this-Header-a-large-number-of-times: Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry, who was a farmer, and Aunt Em, who was the farmer's wife. Their house was small, for the lumber to build it had to be carried by wagon many miles. There were four walls, a floor and a roof, which made one room; and this room contained a rusty looking cookstove, a cupboard for the dishes, a table, three or four chairs, and the beds. Uncle Henry and Aunt Em had a big bed in one corner, and Dorothy a little bed in another corner. There was no garret at all, and no cellar--except a small hole dug in the ground, called a cyclone cellar, where the family could go in case one of those great whirlwinds arose, mighty enough to crush any building in its path. It was reached by a trap door in the middle of the floor, from which a ladder led down into the small, dark hole.%0a]%
 -foo-
 </data>
 </reply>
diff --git a/tests/data/test747 b/tests/data/test747
new file mode 100644 (file)
index 0000000..6b541a4
--- /dev/null
@@ -0,0 +1,56 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+%repeat[5001 x Tiny: but many.%0a]%
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+Reject too many HTTP response headers
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="yes">
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+# curl: (100) Too many response headers, 5000 is max
+<errorcode>
+100
+</errorcode>
+</verify>
+</testcase>