Status: Patched
This vulnerability has been verified as resolved and deployed.
gRPC forwarded headers can overflow the upstream HPACK request buffer (CVE-2026-42055)
Summary
NGINX gRPC upstream sizing reserved four HPACK length bytes but serialized larger raw header strings with five
When an HTTP/1.x request reaches a grpc_pass location, NGINX forwards client request headers by default. Before the fix, ngx_http_grpc_create_request() sized each forwarded header name and value with the fixed NGX_HTTP_V2_INT_OCTETS allowance of four HPACK integer bytes, then later serialized the same strings through the variable-length HPACK encoder.
If ignore_invalid_headers off allowed invalid raw-unfriendly header names to be retained, and large_client_header_buffers allowed multi-megabyte header lines, an unauthenticated client could send forwarded header names and values of NGX_HTTP_V2_MAX_FIELD + 1 bytes. For raw HPACK strings at that length, the encoder emits a five-byte length prefix while the allocation budget reserved four. The final request buffer was therefore undersized, and the continuation-frame insertion path could write beyond b->end.
F5 published the issue as CVE-2026-42055 in advisory K000161584, CWE-122, with CVSS 3.1 score 8.1. The public NGINX 1.31.2 changelog describes worker heap memory corruption or segmentation fault when ignore_invalid_headers off and large large_client_header_buffers are used while proxying a crafted request to an HTTP/2 or gRPC backend. NGINX fixed both affected upstream builders in commit 26d824e, merged through PR #1474, and credited Mufeed VH of Winfunc Research.
CVSS Score
Vulnerability Location
Source-to-Sink Analysis
The HTTP/1.x parser can mark unusual header-name bytes as invalid without immediately rejecting the header line. Bytes such as ~ are useful for this proof because they also force raw HPACK encoding instead of a shorter Huffman representation.
Invalid headers are skipped only when ignore_invalid_headers is enabled. With ignore_invalid_headers off, NGINX keeps the attacker-controlled header name and value lengths in r->headers_in.headers.
The gRPC upstream configuration passes client request headers by default, so accepted client headers flow into the upstream HTTP/2/gRPC request builder unless explicitly filtered.
The vulnerable sizing pass used a fixed four-octet HPACK integer budget for each forwarded header name and value. That budget is only sound while the HPACK string length is at most NGX_HTTP_V2_MAX_FIELD.
NGX_HTTP_V2_MAX_FIELD is derived from the four-octet HPACK integer allowance. A raw string of 2,097,279 bytes is one byte over that boundary and requires an additional continuation byte.
Serialization used the real HPACK string encoder for the same forwarded name and value. ngx_http_v2_write_int() writes as many continuation bytes as the value requires, so the write can exceed the earlier fixed budget.
The upstream fix rejects forwarded header names and values above NGX_HTTP_V2_MAX_FIELD before adding them to the buffer length, restoring the invariant that four reserved HPACK integer octets are enough.
Impact Analysis
Critical Impact
The demonstrated impact is a remote, unauthenticated heap out-of-bounds write in an NGINX worker process under restrictive non-default configuration. The ASAN proof aborts the worker in ngx_http_grpc_create_request(), confirming availability impact and heap memory corruption. The public CVE record states that code execution is possible when ASLR is disabled or bypassed; this entry does not claim a completed production code-execution exploit.
Attack Surface
NGINX Open Source and NGINX Plus deployments with a reachable grpc_pass location. The public CVE record lists affected Open Source ranges as 1.13.10 before 1.31.2 on mainline and 1.30.2 before 1.30.3 on stable, with NGINX Plus R36 and R37 patch ranges also affected.
Preconditions
The location must use grpc_pass; request-header forwarding must remain enabled; ignore_invalid_headers off must allow invalid raw header names to be retained; and large_client_header_buffers must allow header lines larger than 2 MiB. Default NGINX settings block this exact trigger because invalid headers are ignored and large header buffers are much smaller.
Proof of Concept
Environment Setup
Build a vulnerable NGINX revision before commit 26d824e, such as e8053c867f9ab14f323e3019ccab585d857abb66, with ASAN and HTTP/2 support:
Target Configuration
Run a disposable localhost-only server with invalid headers retained and very large header buffers:
Exploit Delivery
Send a request containing two forwarded headers where both the name and value are 2,097,279 ~ bytes:
The proof model reported allocated=8393824, final_size=8393825, and overflow_bytes=1 for the corrected trigger. A short-name/value-only control stayed below the allocation.
Outcome
The ASAN report confirms heap memory corruption while constructing the upstream gRPC request. After commit 26d824e, the oversized header name or value is rejected before allocation and serialization, so no worker abort or ASAN heap-buffer-overflow should occur.
Expected Response: A vulnerable ASAN build aborts in the worker with:
Run this level of analysis on your repo.
Winfunc traces source-to-sink paths, validates exploitability, and gives your team patch-ready remediation.
