]> git.kaiwu.me - nginx.git/commitdiff
HTTP/2: limit Content-Type and Location response header length
authorRoman Arutyunyan <arut@nginx.com>
Sun, 26 Apr 2026 16:20:26 +0000 (20:20 +0400)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Fri, 15 May 2026 12:23:39 +0000 (16:23 +0400)
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.

src/http/v2/ngx_http_v2_filter_module.c

index 6b73b1e6876915478df765bd65662ec640944fc3..aabc5ac1b6e17b97a230c5d54e2eaa903815ca02 100644 (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)
         {