]> git.kaiwu.me - nginx.git/commitdiff
Request body: flood detection for chunked request body
authorSourav Bhowmik <s.bhowmik@f5.com>
Tue, 4 Aug 2026 13:34:19 +0000 (06:34 -0700)
committerSergey Kandaurov <pluknet@nginx.com>
Wed, 4 Nov 2026 20:42:24 +0000 (00:42 +0400)
Chunk sizes (including leading zeros), chunk extensions and trailers
of a chunked request body were not accounted, allowing a client to send
an unbounded amount of framing with little or no body data.

Now all received bytes are counted in rb->received and compared to
the body data, using the same flood detection as in HTTP/2 and HTTP/3.

Reported by jskoetsier.

src/http/ngx_http_request_body.c

index 1d8e4081ab5bfac21aa5144e5b4513f3a4bb9c3e..d9d0c22e3961ff35eba5d59f3b353a9818570944 100644 (file)
@@ -1090,6 +1090,7 @@ static ngx_int_t
 ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
 {
     size_t                     size;
+    u_char                    *p;
     ngx_int_t                  rc;
     ngx_buf_t                 *b;
     ngx_chain_t               *cl, *out, *tl, **ll;
@@ -1121,6 +1122,7 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
     for (cl = in; cl; cl = cl->next) {
 
         b = NULL;
+        p = cl->buf->pos;
 
         for ( ;; ) {
 
@@ -1259,6 +1261,18 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
 
             return NGX_HTTP_BAD_REQUEST;
         }
+
+        rb->received += cl->buf->pos - p;
+
+        if (rb->received / 8 > r->headers_in.content_length_n + 1048576) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent too large chunked body "
+                          "overhead: %O+%O bytes",
+                          r->headers_in.content_length_n,
+                          rb->received - r->headers_in.content_length_n);
+
+            return NGX_HTTP_BAD_REQUEST;
+        }
     }
 
     rc = ngx_http_top_request_body_filter(r, out);