CVE-2026-58055 Overview
CVE-2026-58055 affects the nghttpx proxy component of nghttp2 through version 1.69.0. The proxy forwards an HTTP/1.1 Upgrade request that carries both a Content-Length header and a body onto reusable keep-alive backend connections. During this forwarding, nghttpx re-adds the Upgrade and Connection headers while passing Content-Length verbatim. A backend that resolves this ambiguous message in the attacker's favor enables HTTP request smuggling and cross-client response-queue poisoning. The flaw is classified under [CWE-444] Inconsistent Interpretation of HTTP Requests.
Critical Impact
Attackers can smuggle requests through nghttpx and poison the response queue shared by other clients, exposing responses intended for different users.
Affected Products
- nghttp2 nghttpx proxy versions up to and including 1.69.0
- Deployments using nghttpx as a reverse proxy in front of HTTP/1.1 backends
- Configurations where backend keep-alive connections are reused across clients
Discovery Timeline
- 2026-06-28 - CVE-2026-58055 published to the National Vulnerability Database (NVD)
- 2026-06-30 - Last updated in NVD database
Technical Details for CVE-2026-58055
Vulnerability Analysis
The vulnerability arises from ambiguous HTTP/1.1 message framing when nghttpx proxies an Upgrade request. HTTP/1.1 semantics disallow combining an Upgrade intent with a Content-Length-delimited body on a persistent connection, because the resulting message has two conflicting interpretations. nghttpx forwards this malformed request onto a keep-alive backend socket and reinserts hop-by-hop headers such as Upgrade and Connection, while relaying the client-supplied Content-Length unchanged.
A backend parser that trusts Content-Length and treats the message as a normal request will read the declared body bytes, then process any trailing bytes as a second, smuggled request. Because the backend connection is reused for subsequent clients, the smuggled request's response can be delivered to an unrelated client. This constitutes response-queue poisoning across tenants sharing the same backend pool.
Root Cause
The root cause is insufficient validation of Upgrade requests before their reuse on shared backend connections. nghttpx did not disqualify a connection from reuse when a request carried both Upgrade semantics and a body. The patch introduces an http1_msg_complete state and requires blocked_request_buf_ to be empty before a downstream connection can be marked reusable.
Attack Vector
Exploitation requires network access to the nghttpx frontend. An attacker sends a crafted HTTP/1.1 request combining an Upgrade header, a Connection: upgrade header, and a Content-Length header with a body containing a second HTTP request. The backend interprets the boundary differently than the proxy, letting the smuggled request bind to the next client's response slot.
// Security patch in src/shrpx_downstream.cc - tightening reuse checks
// state, especially for HTTP/1.1
return dconn_ && response_state_ == DownstreamState::MSG_COMPLETE &&
request_state_ == DownstreamState::MSG_COMPLETE && !upgraded_ &&
- !resp_.connection_close && request_buf_.rleft() == 0;
+ !resp_.connection_close && blocked_request_buf_.rleft() == 0 &&
+ request_buf_.rleft() == 0;
}
DefaultMemchunks Downstream::pop_response_buf() {
// Source: https://github.com/nghttp2/nghttp2/commit/ab28105c4a0197da24f8bfc414bc116055249e1e
Detection Methods for CVE-2026-58055
Indicators of Compromise
- HTTP/1.1 requests to nghttpx containing both Upgrade and Content-Length headers with a non-empty body
- Backend access logs showing request boundaries that do not match proxy access logs for the same connection
- Responses delivered to clients that reference resources the client never requested
- Unexpected Connection: upgrade sequences on reused keep-alive backend sockets
Detection Strategies
- Inspect frontend request logs for the header combination Upgrade + Content-Length + body length greater than zero and correlate to the same 5-tuple as follow-on requests
- Compare request counts between the nghttpx frontend and each backend origin; drift indicates smuggling
- Deploy WAF or reverse-proxy rules that reject ambiguous framing before it reaches nghttpx
- Enable verbose access logging with request IDs to trace responses back to the originating client
Monitoring Recommendations
- Alert on any HTTP request containing both Transfer-Encoding or Upgrade and Content-Length headers
- Track anomalies in backend keep-alive session length and requests-per-connection ratios
- Monitor for cross-user data leakage patterns in application-layer telemetry
- Review authentication and session tokens appearing on unexpected client responses
How to Mitigate CVE-2026-58055
Immediate Actions Required
- Upgrade nghttpx to the fixed release that includes commit ab28105c4a0197da24f8bfc414bc116055249e1e
- Audit reverse proxy configurations to identify all deployments running nghttp2 1.69.0 or earlier
- Disable HTTP/1.1 Upgrade forwarding on nghttpx where WebSocket or protocol upgrade is not required
- Restrict backend connection reuse for requests that carry hop-by-hop semantics
Patch Information
The upstream fix is available in the nghttp2 GitHub commit ab28105, which tightens CONNECT and HTTP Upgrade handling. The patch adds an http1_msg_complete flag on Downstream and requires blocked_request_buf_ to be drained before a connection is treated as reusable. Additional context is documented in the VulnCheck Security Advisory.
Workarounds
- Terminate HTTP/1.1 at a front-end proxy that strictly rejects Upgrade requests carrying a Content-Length body
- Force Connection: close on backend requests that include an Upgrade header to prevent connection reuse
- Deploy a WAF rule that drops requests containing both Upgrade and non-zero Content-Length
- Segment backend pools per tenant to limit blast radius of response-queue poisoning
# Example WAF rule (ModSecurity) to block ambiguous Upgrade + Content-Length requests
SecRule REQUEST_HEADERS:Upgrade "@rx .+" \
"id:1005801,phase:1,deny,status:400,\
chain,msg:'CVE-2026-58055: Ambiguous Upgrade + Content-Length'"
SecRule REQUEST_HEADERS:Content-Length "@gt 0"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

