From: Daniel Stenberg Date: Sat, 16 Sep 2023 21:54:44 +0000 (+0200) Subject: http: use per-request counter to check too large headers X-Git-Tag: curl-8_4_0~183 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2cb0d346aaacbe8aae7ba19f42190d802a038972;p=thirdparty%2Fcurl.git http: use per-request counter to check too large headers Not the counter that accumulates all headers over all redirects. Follow-up to 3ee79c1674fd6 Do a second check for 20 times the limit for the accumulated size for all headers. Fixes #11871 Reported-by: Joshix-1 on github Closes #11872 --- diff --git a/lib/http.c b/lib/http.c index 4344b9dae5..e74aba3228 100644 --- a/lib/http.c +++ b/lib/http.c @@ -3970,18 +3970,23 @@ CURLcode Curl_bump_headersize(struct Curl_easy *data, bool connect_only) { size_t bad = 0; + unsigned int max = MAX_HTTP_RESP_HEADER_SIZE; if(delta < MAX_HTTP_RESP_HEADER_SIZE) { + data->info.header_size += (unsigned int)delta; + data->req.allheadercount += (unsigned int)delta; if(!connect_only) data->req.headerbytecount += (unsigned int)delta; - data->info.header_size += (unsigned int)delta; - if(data->info.header_size > MAX_HTTP_RESP_HEADER_SIZE) + if(data->req.allheadercount > max) + bad = data->req.allheadercount; + else if(data->info.header_size > (max * 20)) { bad = data->info.header_size; + max *= 20; + } } else - bad = data->info.header_size + delta; + bad = data->req.allheadercount + delta; if(bad) { - failf(data, "Too large response headers: %zu > %u", - bad, MAX_HTTP_RESP_HEADER_SIZE); + failf(data, "Too large response headers: %zu > %u", bad, max); return CURLE_RECV_ERROR; } return CURLE_OK; diff --git a/lib/urldata.h b/lib/urldata.h index 4bfb3b48d2..c6e69f3db9 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -640,7 +640,9 @@ struct SingleRequest { curl_off_t pendingheader; /* this many bytes left to send is actually header and not body */ struct curltime start; /* transfer started at this time */ - unsigned int headerbytecount; /* only count received headers */ + unsigned int headerbytecount; /* received server headers (not CONNECT + headers) */ + unsigned int allheadercount; /* all received headers (server + CONNECT) */ unsigned int deductheadercount; /* this amount of bytes doesn't count when we check if anything has been transferred at the end of a connection. We use this