From: Daniel Stenberg Date: Wed, 7 May 2025 22:21:26 +0000 (+0200) Subject: headers: enforce a max number of response header to accept X-Git-Tag: curl-8_14_0~138 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40ef77b6dadbd6dbedcd2963fccb817673c430b8;p=thirdparty%2Fcurl.git headers: enforce a max number of response header to accept 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 --- diff --git a/lib/headers.c b/lib/headers.c index c1ff58c931..9f522ecc13 100644 --- a/lib/headers.c +++ b/lib/headers.c @@ -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) diff --git a/lib/http.h b/lib/http.h index ba7a121d09..8876f38044 100644 --- a/lib/http.h +++ b/lib/http.h @@ -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 */ diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index cf372baa41..e3571be557 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -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 \ diff --git a/tests/data/test498 b/tests/data/test498 index 6d9454c066..6c9f8d239e 100644 --- a/tests/data/test498 +++ b/tests/data/test498 @@ -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- diff --git a/tests/data/test747 b/tests/data/test747 new file mode 100644 index 0000000000..6b541a4337 --- /dev/null +++ b/tests/data/test747 @@ -0,0 +1,56 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + +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- + + + +# +# Client-side + + +http + + +Reject too many HTTP response headers + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + +# curl: (100) Too many response headers, 5000 is max + +100 + + +