From: Vadim Zhestikov Date: Wed, 19 Aug 2026 19:41:08 +0000 (-0700) Subject: FastCGI: support for multibyte parameter name lengths. X-Git-Tag: release-1.31.5~19 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=6ae731d074b015be859c3d4ddcaddbaf0dfad8ed;p=nginx.git FastCGI: support for multibyte parameter name lengths. The name length of a configured parameter was truncated to one byte before the per-parameter length field was written, so that a fastcgi_param name of 128 bytes or longer was encoded with a wrong length while the name itself was copied in full. The resulting request was malformed, and upstream servers responded by closing the connection. While long names are barely used in practice, it is easy to support them. The length is now properly encoded up to the allowed length. --- diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index 96e0b3b5d..7e8953ab1 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -915,7 +915,8 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) continue; } - params_len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len; + params_len += ((key_len > 127) ? 4 : 1) + key_len + + ((val_len > 127) ? 4 : 1) + val_len; } len += params_len; @@ -1083,7 +1084,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; - key_len = (u_char) lcode(&le); + key_len = lcode(&le); lcode = *(ngx_http_script_len_code_pt *) le.ip; skip_empty = lcode(&le); @@ -1107,13 +1108,23 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) continue; } - if (ngx_http_script_check_length(&e, 1 + ((val_len > 127) ? 4 : 1)) + if (ngx_http_script_check_length(&e, + ((key_len > 127) ? 4 : 1) + + ((val_len > 127) ? 4 : 1)) != NGX_OK) { return NGX_ERROR; } - *e.pos++ = (u_char) key_len; + if (key_len > 127) { + *e.pos++ = (u_char) (((key_len >> 24) & 0x7f) | 0x80); + *e.pos++ = (u_char) ((key_len >> 16) & 0xff); + *e.pos++ = (u_char) ((key_len >> 8) & 0xff); + *e.pos++ = (u_char) (key_len & 0xff); + + } else { + *e.pos++ = (u_char) key_len; + } if (val_len > 127) { *e.pos++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);