http: return error when receiving too large header set

To avoid abuse. The limit is set to 300 KB for the accumulated size of
all received HTTP headers for a single response. Incomplete research
suggests that Chrome uses a 256-300 KB limit, while Firefox allows up to
1MB.

Closes #11582
This commit is contained in:
Daniel Stenberg 2023-08-02 23:34:48 +02:00
parent 944e219f10
commit 3ee79c1674
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
6 changed files with 60 additions and 20 deletions

View file

@ -3920,6 +3920,29 @@ static CURLcode verify_header(struct Curl_easy *data)
return CURLE_OK;
}
CURLcode Curl_bump_headersize(struct Curl_easy *data,
size_t delta,
bool connect_only)
{
size_t bad = 0;
if(delta < MAX_HTTP_RESP_HEADER_SIZE) {
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)
bad = data->info.header_size;
}
else
bad = data->info.header_size + delta;
if(bad) {
failf(data, "Too large response headers: %zu > %zu",
bad, MAX_HTTP_RESP_HEADER_SIZE);
return CURLE_RECV_ERROR;
}
return CURLE_OK;
}
/*
* Read any HTTP header lines from the server and pass them to the client app.
*/
@ -4173,8 +4196,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(result)
return result;
data->info.header_size += (long)headerlen;
data->req.headerbytecount += (long)headerlen;
result = Curl_bump_headersize(data, headerlen, FALSE);
if(result)
return result;
/*
* When all the headers have been parsed, see if we should give
@ -4496,8 +4520,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(result)
return result;
data->info.header_size += Curl_dyn_len(&data->state.headerb);
data->req.headerbytecount += Curl_dyn_len(&data->state.headerb);
result = Curl_bump_headersize(data, Curl_dyn_len(&data->state.headerb),
FALSE);
if(result)
return result;
Curl_dyn_reset(&data->state.headerb);
}