REDHAT-BUG-2536964: Medium severity maven/io.netty/netty-codec-http vulnerability

Published Sep 18, 2026
·
Updated

Netty split Transfer-Encoding fields bypass final-chunked validation and enable request smuggling

A public GitHub Security Advisory (GHSA-3jrc-fchc-59pw) describes the following issue:

Summary

pov: pov-test

Netty's HTTP/1.1 decoder added RFC 9112 validation for malformed Transfer-Encoding order in the fix family for GHSA-38f8-5428-x5cv / CVE-2026-42585. That validation rejects the single-field case Transfer-Encoding: chunked, identity, but it can be bypassed when equivalent ordering is expressed as multiple header fields and the last field value is a short non-final transfer coding such as gzip or deflate.

For example:

text Transfer-Encoding: chunked Transfer-Encoding: gzip

is equivalent to the combined field value:

text Transfer-Encoding: chunked, gzip

In that value, chunked is not the final transfer coding. A request recipient must reject this message under RFC 9112 framing rules. Netty instead treats the message as chunked, accepts the terminating zero-size chunk, and parses a following request as a second request on the same connection.

This creates an HTTP request-smuggling primitive when Netty is paired with an intermediary or peer that rejects, buffers, or differently interprets the same invalid transfer-coding order.

This should be triaged as a current supported-release bypass/incomplete fix in the malformed Transfer-Encoding family. It is not a claim that malformed split Transfer-Encoding risk was never discussed publicly: Netty issue #9861 raised closely related behavior in 2019, and the May 2026 GHSA-38f8-5428-x5cv advisory fixed a single-field instance of the same ordering rule. The current issue is that latest supported releases still accept the split-field form after those fixes.

Technical Details

HttpUtil.isTransferEncodingChunked(...) returns true if any Transfer-Encoding field contains the comma-separated token chunked:

text codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java:362 codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java:363

HttpHeaders.containsValue(...) checks comma-separated values across header fields:

text codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaders.java:1600 codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaders.java:1603

Once any chunked value is found, HttpObjectDecoder enters chunked decoding. It then validates only the final Transfer-Encoding field value:

text codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java:853 codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java:859 codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java:861

The validation has a length guard:

text codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java:863 codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java:865 codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java:867

The comment says that if the final value is not longer than chunked, Netty knows it is only chunked. That assumption is false for final values like gzip and deflate. As a result:

- Transfer-Encoding: chunked, identity is rejected. - Transfer-Encoding: chunked followed by Transfer-Encoding: gzip is accepted. - Transfer-Encoding: chunked followed by Transfer-Encoding: deflate is accepted.

Git blame ties this validation block to the May 4, 2026 hardening commit:

text 977661f71f7511ad68ca17cabd7b5185efb978f4 Motivation: RFC9112 specified that chunked must be the last encoding so we should verify this.

PoC

Run the local PoV:

fish cd oss-zero-day-harness bash submission-bundle/netty-pov-test-transfer-encoding-order-bypass/poc/reproduce.sh

The key request shape is:

text POST /one HTTP/1.1\r\n Host: target\r\n Transfer-Encoding: chunked\r\n Transfer-Encoding: gzip\r\n \r\n 0\r\n \r\n GET /two HTTP/1.1\r\n Host: target\r\n \r\n

Observed on current 4.2:

text CASE splitfieldschunkedthengzipaccepted request uri=/one result=success transferEncoding=[chunked, gzip] lastContent bytes=0 result=success request uri=/two result=success transferEncoding=[] lastContent bytes=0 result=success

The same run confirms the patched single-field case is rejected:

text CASE singlefieldchunkedthenidentityrejected request uri=/one result=failure(java.lang.IllegalArgumentException:chunked must be the last encoding present in the Transfer-Encoding header) transferEncoding=[chunked, identity]

The supplementary Content-Length case is rejected on current 4.2:

text CASE splitfieldschunkedthengzipwithcontentlengthrejected request uri=/one result=failure(io.netty.handler.codec.http.ContentLengthNotAllowedException:Content-Length are not allowed in HTTP/1.1 messages that contains a Transfer-Encoding header.) transferEncoding=[chunked, gzip]

Impact

HTTP request smuggling can bypass front-end routing and access-control decisions, desynchronize request processing, or cause a following request to be processed in an unintended context. The exploitability of this primitive depends on a deployment with a parser differential, but Netty is the component that accepts the malformed framing and splits the stream into two requests.

The included PoV also checks a Content-Length variant. Current Netty rejects split Transfer-Encoding plus Content-Length with ContentLengthNotAllowedException. This report therefore does not claim the exact CL.TE exploitation shape from GHSA-38f8-5428-x5cv; it claims the TE-only split-field final-coding bypass that remains in current supported releases.

The PoV is local-only. It uses EmbeddedChannel and HttpRequestDecoder; it does not contact any live service.

Suggested Fix

Parse Transfer-Encoding as one ordered list across all field lines before deciding whether to enter chunked decoding. The decoder should reject HTTP/1.1 requests when the final transfer-coding to

[truncated]

Affected: - maven:io.netty:netty-codec-http affected >=4.2.12.Final; fixed unknown - maven:io.netty:netty-codec-http affected >=4.1.132.Final; fixed unknown

Fixed versions: see advisory

Advisory: https://github.com/netty/netty/security/advisories/GHSA-3jrc-fchc-59pw

Affected Software

1 affected component
maven/io.netty/netty-codec-http>=undefined

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Compensating control

    Deploy a compensating request-framing mitigation (e.g., normalize/reject malformed HTTP/1.1 Transfer-Encoding header ordering at the front-end/proxy) because Netty may accept split-field Transfer-Encoding ordering that can enable request smuggling when paired with a parser differential.

Event History

Sep 18, 2026
Data Sourced
via Red Hat·10:30 AM
DescriptionSeverityAffected Software

Frequently Asked Questions

1

What request format is needed to trigger the parsing discrepancy?

The request must use multiple Transfer-Encoding header fields so that chunked is followed by a non-final coding in a later field, such as “Transfer-Encoding: chunked” followed by “Transfer-Encoding: gzip” or “deflate.” Netty treats this as chunked and accepts a terminating zero-size chunk even though RFC 9112 requires rejection.

2

When can this become a request-smuggling issue?

The issue creates a request-smuggling primitive when Netty is paired with an intermediary or peer that handles the malformed Transfer-Encoding ordering differently. After accepting the zero-size chunk, Netty can parse following bytes as a second request on the same connection.

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