Jun 15, 2026·7 min read·3 visits
Netty's HTTP decoder silently skips leading non-CRLF control characters (like SOH or NUL), allowing attackers to smuggle HTTP requests through reverse proxies.
CVE-2026-50020 is a medium-severity HTTP Request Smuggling/Response Smuggling vulnerability (CWE-444) within the Netty asynchronous network application framework. The flaw resides in Netty's HTTP codec implementation, specifically the HttpObjectDecoder class, which silently consumes arbitrary ISO control bytes preceding the first request line.
Netty is an asynchronous, event-driven network application framework used extensively in the enterprise Java ecosystem for building high-performance protocol servers and clients. The framework serves as the underlying networking layer for major projects, including Spring Boot WebFlux, Vert.x, Quarkus, and various API gateways. Because Netty handles raw socket parsing directly, flaws within its parsing logic expose a highly critical attack surface to the public internet.
This specific vulnerability, tracked as CVE-2026-50020 and natively as GHSA-hvcg-qmg6-jm4c, resides in Netty's HTTP codec module, specifically inside the HttpObjectDecoder class. The component is responsible for parsing raw incoming byte streams into structured HTTP request and response objects. A parsing inconsistency in this decoder allows remote attackers to perform HTTP request smuggling, a class of vulnerability categorized under CWE-444.
The vulnerability occurs when Netty acts as a backend server positioned behind an intermediary reverse proxy, load balancer, or web application firewall (WAF). If the upstream proxy handles invalid leading control characters differently than Netty, an attacker can exploit this discrepancy to bypass front-end security controls. The impact is restricted to architectures where persistent TCP connections are shared or reused between the proxy and the backend server.
The root cause of CVE-2026-50020 lies in Netty's overly lenient handling of leading characters preceding the first HTTP request line. According to the HTTP/1.1 specification outlined in RFC 9112 §2.2, a robust HTTP parser is permitted to tolerate empty lines before a request. Specifically, the specification states that a server expecting to parse a request line should ignore at least one empty line (CRLF) received prior to that request line. This allowance is restricted strictly to carriage return and line feed characters.
In vulnerable versions of Netty, the parser implements a broader robustness logic that goes far beyond the RFC mandate. The HttpObjectDecoder class attempts to skip what it classifies as control characters and whitespace before beginning the extraction of the request method, URI, and version. To identify these bytes, Netty utilizes the static array ISO_CONTROL_OR_WHITESPACE initialized using Java's Character.isISOControl(b) helper method.
The application of Character.isISOControl introduces a major security deviation. In the Java language specification, this method evaluates to true for any byte value within the range of 0x00 through 0x1F, as well as 0x7F. This range includes characters such as NUL (0x00), SOH (0x01), STX (0x02), and other control sequences that are completely distinct from standard CRLF whitespace characters. When Netty encounters these bytes preceding an HTTP request line, it silently discards them instead of rejecting the stream as malformed.
To understand the architectural defect, we must examine the implementation of LineParser.skipControlChars in the vulnerable versions. The method utilizes a ByteProcessor to loop over the inbound buffer, advancing the reader index past any byte that matches the ISO_CONTROL_OR_WHITESPACE map. This processing logic effectively ignores illegal bytes, shifting the starting index of the actual HTTP request line forward.
// Vulnerable logic in HttpObjectDecoder.java
private static void skipControlChars(ByteBuf buffer) {
for (;;) {
int i = buffer.forEachByte(SKIP_CONTROL_CHARS_BYTES);
if (i == -1) {
buffer.readerIndex(buffer.writerIndex());
break;
}
buffer.readerIndex(i);
// Arbitrary control characters (0x00-0x1F) are silently consumed
}
}The patch introduced in versions 4.1.135.Final and 4.2.15.Final addresses this behavior by replacing the generic ISO control check with a strict validation routine. The updated logic verifies that only valid CRLF sequences are bypassed. Any occurrence of non-CRLF control characters preceding the request line now immediately terminates the parsing sequence and registers a decoder failure, preventing the smuggling of subsequent requests.
By ensuring that non-CRLF bytes trigger an immediate protocol violation, the updated parser aligns with RFC 9112 §2.2. The fix effectively eliminates the semantic gap between the proxy and Netty. Because the backend now rejects any leading bytes that are not CRLF, the proxy's view of the request stream remains synchronized with the backend's interpretation.
Exploitation of CVE-2026-50020 relies on establishing a desynchronized state between the front-end reverse proxy and the backend Netty server. An attacker begins by crafting an HTTP pipelined payload containing two logical requests. The first request is a standard, syntactically valid HTTP POST request containing a body, while the second is a smuggled request prefixed with an arbitrary non-CRLF control character like SOH (0x01).
The front-end proxy inspects the initial POST request, reads the Content-Length header, and maps the entire body (including the smuggled request and its leading SOH byte) as payload data. It does not parse the payload as an independent HTTP request because it is contained within the POST request boundary. The proxy then routes the combined byte stream to the Netty backend over a shared, persistent connection.
When the Netty backend receives the stream, it processes the first POST request and executes the associated application handler. Once completed, Netty looks for the next request on the same TCP channel. It encounters the SOH byte, identifies it as an ISO control character, and silently ignores it. Netty then processes the immediate subsequent bytes as a brand new, independent HTTP request, allowing the attacker to bypass the proxy's routing restrictions.
The direct impact of CVE-2026-50020 is a complete bypass of front-end security controls. In modern architectures, reverse proxies are frequently used to enforce authentication, inspect authorization headers, and restrict access to administrative endpoints. By smuggling requests, an attacker can query these restricted endpoints directly because the proxy only validates the outer POST request.
Beyond access control bypasses, this request smuggling flaw can lead to cache poisoning if the front-end proxy caches responses based on request URIs. An attacker can orchestrate a scenario where a smuggled request causes the backend to return a malicious response, which the proxy then associates with a public URI. Consequently, subsequent legitimate users requesting that public URI are served the poisoned cache content.
The CVSS v3.1 base score is calculated at 5.3 (Medium) with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N. While the technical severity is medium because the vulnerability requires a specific proxy-backend configuration, the operational risk is high due to the ubiquity of Netty in cloud-native Java environments. Organizations employing Netty backends behind load balancers must prioritize patching to maintain boundary integrity.
Remediation requires upgrading Netty components to secure versions. For environments utilizing the 4.1.x release line, teams must update netty-codec-http to version 4.1.135.Final or higher. For applications built on the 4.2.x release line, the dependency must be updated to version 4.2.15.Final or higher. Transitive dependency resolution tools should be configured to enforce these versions globally.
In scenarios where immediate upgrading is unfeasible, several defense-in-depth mitigations can reduce the threat vector. The most effective workaround is to disable connection keep-alive or pipeline reuse between the proxy and the Netty backend. If the proxy establishes a fresh TCP socket for every individual backend request, the boundary desynchronization necessary for request smuggling cannot occur.
Additionally, migrating the backend connection protocol from HTTP/1.1 to HTTP/2 offers robust protection. HTTP/2 utilizes binary framing to separate requests, rendering the protocol immune to text-delimited parsing errors like leading-byte smuggling. Finally, security teams can configure their front-end proxies or WAFs to detect and reject any request payloads containing raw binary control characters in the body of HTTP/1.1 requests.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
netty-codec-http Netty Project | >= 4.1.0, < 4.1.135.Final | 4.1.135.Final |
netty-codec-http Netty Project | >= 4.2.0, < 4.2.15.Final | 4.2.15.Final |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-444 |
| Attack Vector | Network |
| CVSS v3.1 Score | 5.3 (Medium) |
| EPSS Score | 0.00232 (0.23%) |
| EPSS Percentile | 13.85% |
| Exploit Status | Proof of Concept (PoC) |
| CISA KEV Status | Not Listed |
The application fails to properly parse or validate incoming HTTP requests in a uniform manner, leading to request boundary confusion.
CVE-2026-48748 is a denial-of-service vulnerability in Netty's HTTP/3 codec (netty-codec-http3) occurring when QPACK dynamic tables are enabled but the blocked streams limit is not explicitly configured. A bug in limit checking and a memory leak in stream tracking allow unauthenticated remote attackers to exhaust the JVM heap memory and crash the server.
CVE-2026-50009 is a cryptographic design vulnerability in the Netty network application framework. Prior to version 4.2.15.Final, the framework's QUIC protocol implementation fails to cryptographically segregate the generated Connection IDs and the associated Stateless Reset Tokens. An on-path network attacker who sniffs traffic during a Connection ID rotation can extract secret token material from cleartext headers, enabling them to inject spoofed reset packets and terminate active connections.
A critical hostname verification bypass vulnerability exists in the Netty network application framework when configured as a TLS client. When a developer registers a custom plain X509TrustManager, Netty wraps it inside an X509TrustManagerWrapper to adapt it to the X509ExtendedTrustManager API. However, this wrapper discards the SSLEngine context, bypassing critical hostname checks. Because the wrapper is identified as an X509ExtendedTrustManager, standard cryptographic engines and Netty's OpenSSL wrappers do not re-wrap it, failing to execute any hostname validation. Consequently, clients silently accept certificates for any host, enabling unauthenticated Man-in-the-Middle (MitM) attacks.
An uncontrolled resource pre-allocation flaw in the Netty Redis codec module allows remote unauthenticated attackers to cause a denial of service (OutOfMemoryError) by sending a crafted Redis Serialization Protocol (RESP) array header.
CVE-2026-50560 describes a vulnerability in Netty's HTTP/2 codec implementation. When acting as an intermediary (such as a reverse proxy, API gateway, or edge server), Netty can be forced into an application-level Denial-of-Service condition. The attack is triggered by negotiating a restrictive SETTINGS_MAX_HEADER_LIST_SIZE from the client, causing Netty to process incoming requests fully, but subsequently crash or abort during outbound response serialization. This results in an asymmetrical consumption of resources on backend systems and thread starvation within the Netty event loop.
A critical supply-chain OS command injection vulnerability exists in the NodejsFunction local bundling pipeline within the AWS Cloud Development Kit (CDK) library (aws-cdk-lib) before version 2.245.0 (and before 2.246.0 on Windows systems). The vulnerability allows a threat actor who can control any of several bundling properties (externalModules, define, loader, inject, or esbuildArgs) to execute arbitrary operating system commands on the host machine running the CDK compilation or deployment toolchain (e.g., during cdk synth, cdk deploy, or cdk diff).