# HG changeset patch
# User Gennady Bekasov <[email protected]>
# Date 1755456060 -10800
# Sun Aug 17 21:41:00 2025 +0300
# Node ID 2a14d182adce88e0ea7bb7ca3bd01e93ee8eee90
# Parent bdfd605f661eea3d272caf1bd5d85e7c539394ca
Added the "proxy_upstream_allow_duplicate_chunked" configuration directive.
diff -r bdfd605f661e -r 2a14d182adce src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c Wed Jul 23 21:53:19 2025 +0300
+++ b/src/http/modules/ngx_http_proxy_module.c Sun Aug 17 21:41:00 2025 +0300
@@ -367,6 +367,13 @@
offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_client_abort),
NULL },
+ { ngx_string("proxy_upstream_allow_duplicate_chunked"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.upstream_allow_duplicate_chunked),
+ NULL },
+
{ ngx_string("proxy_bind"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
ngx_http_upstream_bind_set_slot,
@@ -3364,6 +3371,7 @@
conf->upstream.request_buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
conf->upstream.force_ranges = NGX_CONF_UNSET;
+ conf->upstream.upstream_allow_duplicate_chunked = NGX_CONF_UNSET;
conf->upstream.local = NGX_CONF_UNSET_PTR;
conf->upstream.socket_keepalive = NGX_CONF_UNSET;
@@ -3494,6 +3502,9 @@
ngx_conf_merge_value(conf->upstream.force_ranges,
prev->upstream.force_ranges, 0);
+ ngx_conf_merge_value(conf->upstream.upstream_allow_duplicate_chunked,
+ prev->upstream.upstream_allow_duplicate_chunked, 0);
+
ngx_conf_merge_ptr_value(conf->upstream.local,
prev->upstream.local, NULL);
diff -r bdfd605f661e -r 2a14d182adce src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c Wed Jul 23 21:53:19 2025 +0300
+++ b/src/http/ngx_http_upstream.c Sun Aug 17 21:41:00 2025 +0300
@@ -5300,7 +5300,11 @@
&h->key, &h->value,
&u->headers_in.transfer_encoding->key,
&u->headers_in.transfer_encoding->value);
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+ if (!u->conf->upstream_allow_duplicate_chunked) {
+ return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+ }
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ "insecure data exchange due to pass duplicate \"Transfer-Encoding\" header as enabled by upstream_allow_duplicate_chunked parameter");
}
if (u->headers_in.content_length) {
diff -r bdfd605f661e -r 2a14d182adce src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h Wed Jul 23 21:53:19 2025 +0300
+++ b/src/http/ngx_http_upstream.h Sun Aug 17 21:41:00 2025 +0300
@@ -177,6 +177,7 @@
ngx_flag_t request_buffering;
ngx_flag_t pass_request_headers;
ngx_flag_t pass_request_body;
+ ngx_flag_t upstream_allow_duplicate_chunked;
ngx_flag_t ignore_client_abort;
ngx_flag_t intercept_errors;
# User Gennady Bekasov <[email protected]>
# Date 1755456060 -10800
# Sun Aug 17 21:41:00 2025 +0300
# Node ID 2a14d182adce88e0ea7bb7ca3bd01e93ee8eee90
# Parent bdfd605f661eea3d272caf1bd5d85e7c539394ca
Added the "proxy_upstream_allow_duplicate_chunked" configuration directive.
diff -r bdfd605f661e -r 2a14d182adce src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c Wed Jul 23 21:53:19 2025 +0300
+++ b/src/http/modules/ngx_http_proxy_module.c Sun Aug 17 21:41:00 2025 +0300
@@ -367,6 +367,13 @@
offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_client_abort),
NULL },
+ { ngx_string("proxy_upstream_allow_duplicate_chunked"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.upstream_allow_duplicate_chunked),
+ NULL },
+
{ ngx_string("proxy_bind"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
ngx_http_upstream_bind_set_slot,
@@ -3364,6 +3371,7 @@
conf->upstream.request_buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
conf->upstream.force_ranges = NGX_CONF_UNSET;
+ conf->upstream.upstream_allow_duplicate_chunked = NGX_CONF_UNSET;
conf->upstream.local = NGX_CONF_UNSET_PTR;
conf->upstream.socket_keepalive = NGX_CONF_UNSET;
@@ -3494,6 +3502,9 @@
ngx_conf_merge_value(conf->upstream.force_ranges,
prev->upstream.force_ranges, 0);
+ ngx_conf_merge_value(conf->upstream.upstream_allow_duplicate_chunked,
+ prev->upstream.upstream_allow_duplicate_chunked, 0);
+
ngx_conf_merge_ptr_value(conf->upstream.local,
prev->upstream.local, NULL);
diff -r bdfd605f661e -r 2a14d182adce src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c Wed Jul 23 21:53:19 2025 +0300
+++ b/src/http/ngx_http_upstream.c Sun Aug 17 21:41:00 2025 +0300
@@ -5300,7 +5300,11 @@
&h->key, &h->value,
&u->headers_in.transfer_encoding->key,
&u->headers_in.transfer_encoding->value);
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+ if (!u->conf->upstream_allow_duplicate_chunked) {
+ return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+ }
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ "insecure data exchange due to pass duplicate \"Transfer-Encoding\" header as enabled by upstream_allow_duplicate_chunked parameter");
}
if (u->headers_in.content_length) {
diff -r bdfd605f661e -r 2a14d182adce src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h Wed Jul 23 21:53:19 2025 +0300
+++ b/src/http/ngx_http_upstream.h Sun Aug 17 21:41:00 2025 +0300
@@ -177,6 +177,7 @@
ngx_flag_t request_buffering;
ngx_flag_t pass_request_headers;
ngx_flag_t pass_request_body;
+ ngx_flag_t upstream_allow_duplicate_chunked;
ngx_flag_t ignore_client_abort;
ngx_flag_t intercept_errors;
