HTTP/2: limit Content-Type and Location response header length

Previously, when these fields were larger than ~2M, the number of bytes
allocated for the field length was insufficient for such a large number.
The deficit is 1 byte up until ~4M, 2 bytes for sizes above, and grows
bigger with even larger fields.

Currently, nginx does not have modules which allow to exploit this
overflow with reasonably large Content-Type and Location.  The reason is
other response fields make up for this deficit.  For example, the Date
header value contains the characters compressed well by Huffman
encoding, which frees up spare bytes in the header buffer.

Reported by Leo Lin.
This commit is contained in:
Roman Arutyunyan 2026-04-26 20:20:26 +04:00 committed by Roman Arutyunyan
parent 18a70a4d58
commit 58a7bc3406

View file

@ -241,6 +241,14 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
}
if (r->headers_out.content_type.len) {
if (r->headers_out.content_type.len > NGX_HTTP_V2_MAX_FIELD) {
ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
"too long response header value: "
"\"Content-Type: %V\"", &r->headers_out.content_type);
return NGX_ERROR;
}
len += 1 + NGX_HTTP_V2_INT_OCTETS + r->headers_out.content_type.len;
if (r->headers_out.content_type_len == r->headers_out.content_type.len
@ -264,6 +272,13 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
if (r->headers_out.location && r->headers_out.location->value.len) {
if (r->headers_out.location->value.len > NGX_HTTP_V2_MAX_FIELD) {
ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
"too long response header value: \"Location: %V\"",
&r->headers_out.location->value);
return NGX_ERROR;
}
if (r->headers_out.location->value.data[0] == '/'
&& clcf->absolute_redirect)
{