Status: Patched
This vulnerability has been verified as resolved and deployed.
HTTP/2 upstream proxy request encoder permits heap overflow with oversized raw headers (CVE-2026-42055)
Summary
NGINX HTTP/2 upstream proxy request encoding under-counted oversized raw forwarded headers
When proxy_http_version 2 sends a request to an HTTP/2 upstream, ngx_http_proxy_v2_create_request() builds an HPACK-compressed request header block. Before the fix, the sizing pass used the same four-byte NGX_HTTP_V2_INT_OCTETS allowance for every forwarded header name and value length, but the serialization pass used the variable HPACK integer encoder.
A request with raw-encoded forwarded header names and values longer than NGX_HTTP_V2_MAX_FIELD makes the actual HPACK length prefix larger than the reserved budget. With enough oversized fields, the serialized header block plus in-place CONTINUATION-frame insertion exceeds the temporary upstream buffer allocation. The proof-backed sink is the ngx_memmove() continuation insertion loop in ngx_http_proxy_v2_create_request().
This is the HTTP/2 proxy half of CVE-2026-42055 / F5 advisory K000161584. The same NGINX 1.31.2 security entry covers both HTTP/2 and gRPC backends, and the F5 CVE record names ngx_http_proxy_v2_module and ngx_http_grpc_module as affected. NGINX fixed the proxy and gRPC request builders together in commit 26d824e, merged through PR #1474.
CVSS Score
Vulnerability Location
Source-to-Sink Analysis
With ignore_invalid_headers off, the HTTP/1.x request path stores invalid but accepted client header names and values in r->headers_in.headers instead of dropping them.
proxy_http_version 2 dispatches the proxied request into the HTTP/2 upstream implementation. That path is reachable only for configurations using the HTTP/2 upstream proxy feature.
The HTTP/2 upstream proxy handler installs ngx_http_proxy_v2_create_request() as the request creator, so accepted client headers flow into this encoder when request-header forwarding is enabled.
The vulnerable sizing pass added each pass-through header with a fixed four-octet HPACK length budget for the name and another four octets for the value.
The serialization pass then wrote the same strings through the real HPACK encoder. Raw strings of 2,097,279 bytes require five HPACK length bytes, not four.
After serialization, the request builder inserts CONTINUATION frame headers in place with ngx_memmove(). The underestimated HPACK block can leave too little slack, turning the frame insertion into the final out-of-bounds write.
The fix applies the same NGX_HTTP_V2_MAX_FIELD guard used by HTTP/2 response header sizing before accounting pass-through request header names and values.
Impact Analysis
Critical Impact
The proven impact is a remote, unauthenticated heap out-of-bounds write in an NGINX worker under restrictive non-default configuration. The ASAN proof confirms a write in ngx_http_proxy_v2_create_request() at the continuation-frame movement sink. Without ASAN, observable behavior depends on allocator state and may range from a failed upstream request to worker crash or memory corruption.
Attack Surface
NGINX Open Source deployments using proxy_http_version 2 to proxy requests to HTTP/2 upstreams. The HTTP/2 upstream proxy feature was introduced in the 1.29.x line, and the combined CVE is fixed in Open Source 1.31.2+ and 1.30.3+.
Preconditions
The request must reach a proxy_pass location configured with proxy_http_version 2; proxy_pass_request_headers must be enabled, which is the default; ignore_invalid_headers off must allow raw-unfriendly header names; and large_client_header_buffers must permit multi-megabyte header lines. The worker must also be able to allocate the large request header buffers and upstream request buffer.
Proof of Concept
Environment Setup
Build a vulnerable NGINX checkout before commit 26d824e, such as e8053c867f9ab14f323e3019ccab585d857abb66, with ASAN and HTTP/2 support:
Target Configuration
Run a disposable localhost-only proxy with HTTP/2 upstream mode and permissive header parsing:
Exploit Delivery
Send seven pass-through headers whose names and values are each 2,097,279 ~ bytes:
The proof model reported budget_total=29362070, allocated=29378198, final_size=29378200, and overflow_bytes=2.
Outcome
The proof confirms heap memory corruption while building the upstream HTTP/2 proxy request. After commit 26d824e, the oversized forwarded header name or value is rejected before HPACK serialization, and the ASAN heap-buffer-overflow no longer appears.
Expected Response: A vulnerable ASAN build reports:
Run this level of analysis on your repo.
Winfunc traces source-to-sink paths, validates exploitability, and gives your team patch-ready remediation.
