REDHAT-BUG-2536976: Command Injection

Published Sep 18, 2026
·
Updated

Unbounded multi-line response accumulation in SmtpResponseDecoder leads to memory-exhaustion DoS

A public GitHub Security Advisory (GHSA-pq4x-537v-r54q) describes the following issue:

Summary io.netty.handler.codec.smtp.SmtpResponseDecoder accumulates the multi-line details of an SMTP response into a per-connection ArrayList<CharSequence> that has NO count or cumulative-size cap. A malicious or MITM SMTP server that withholds the space-separated terminator line and streams unbounded 250-x\r\n continuation lines drives that list to grow without bound across decode() invocations, exhausting the JVM heap and killing the Netty-based SMTP client/MTA process (Denial of Service).

Root Cause this.details (SmtpResponseDecoder.java:35, ArrayList<CharSequence>) is written only at :66 (set to null on the terminator), :85 (new list), and :87 (add). A grep of the file for maxNum/size()/any cumulative cap returns only maxLineLength — a per-line bound, not an aggregate one. Accumulation resets ONLY on the space-separator branch (:64, resets this.details=null at :66); the '-' continuation branch (:79-89) never resets or caps. A server that sends only 250-x\r\n (continuation) and never 250 x\r\n (terminator) grows details forever. The decoded per-line frame is released at :94, but the retained String copies (:59) in details are not, so nothing frees the accumulated memory. LineBasedFrameDecoder.maxLength (LineBasedFrameDecoder.java:44-45,:112) bounds only each individual line — no aggregate/message-level cap exists anywhere in the module.

This is the unpatched structural sibling of CVE-2026-44891, which added a maxNumHeaders cap to StompSubframeDecoder (the only other LineBasedFrameDecoder subclass). SmtpResponseDecoder was never given the analogous cap. It is also the same bug class Netty already published at MEDIUM in GHSA-q4f6-jm68-57ww (unbounded per-connection queue growth -> DoS).

Impact Heap exhaustion -> OutOfMemoryError -> total availability loss (process crash) of the SMTP client/MTA. Client-side decoder: the attacker must occupy the server side of the connection (attacker-controlled MX for direct-to-MX delivery, user/tenant-supplied SMTP host, mail-testing tooling, or a STARTTLS-downgrade MITM on cleartext SMTP).

Proof of Concept Stand up an SMTP listener that, upon any client connection, repeatedly writes 250-x\r\n and never sends a space-separated terminator (250 x\r\n). Point a Netty pipeline containing SmtpResponseDecoder at it. details grows one retained String (~40-60 bytes) per 7-byte line until the client heap is exhausted.

Attack Chain 1. Entry: a Netty-based SMTP client/MTA (pipeline contains SmtpResponseDecoder) opens a connection to an attacker-controlled or MITM'd SMTP server. - Guard: none at connect; TLS is no barrier when the attacker owns the endpoint or downgrades STARTTLS on cleartext SMTP. - Bypass proof: the class is client-side by construction (decodes server responses; SmtpResponseDecoderTest.java:148 instantiates it for inbound decoding). MTAs connect to remote-controlled MX servers by design. 2. Check/Feed continuation lines: server streams 250-x\r\n (7 bytes, non-empty detail) repeatedly, each below maxLineLength. - Guard: LineBasedFrameDecoder.maxLength per-line bound (LineBasedFrameDecoder.java:112). - Bypass proof: each 7-byte line is far below maxLineLength; the check never inspects details. Every line takes the '-' branch (:79) -> details.add(detail) (:87). 3. Withhold terminator: server never sends the space-separated 250 x\r\n line. - Guard: the only reset of this.details is the space branch at :66; there is no count/size cap on the '-' path. - Bypass proof: writes to this.details occur only at :66 (null), :85 (new), :87 (add) - confirmed by grep; no details.size()/maxNum check exists. details is an instance field (:35) persisting across decode() calls. 4. Sink: this.details and its retained String elements grow without bound across decode() invocations (:87). - Guard: none - no aggregate frame/message limit; the per-line frame is released at :94 but the retained String copy (:59) is not. - Bypass proof: LineBasedFrameDecoder bounds only per-line length; nothing caps cumulative retained objects. 5. Impact: OutOfMemoryError -> DoS of the SMTP client/MTA process.

Bypass Evidence - On latest release tag netty-4.2.16.Final, git show netty-4.2.16.Final:.../SmtpResponseDecoder.java shows new ArrayList<CharSequence>(4) (:85) and details.add(detail) (:69/:87) with NO cap; only maxLineLength is present. - grep -rnE "maxNum|maxDetails|maxLines|TooLongFrameException" codec-smtp/ returns NONE — no aggregate cap anywhere in the module. - git log netty-4.2.16.Final..HEAD -- SmtpResponseDecoder.java is empty — no post-release fix. - Contrast: the sibling StompSubframeDecoder HAS maxNumHeaders -> TooLongFrameException; SMTP has no equivalent. - Dedup clean: netty's published advisories contain no SmtpResponseDecoder/codec-smtp memory-exhaustion entry (the only codec-smtp advisory, GHSA-jq43-27x9-3v86, is SMTP command injection — a different class).

Affected Versions io.netty:netty-codec-smtp <= 4.2.16.Final (all released versions; the 4.1.x line is likewise affected — the decoder has had no aggregate cap since its 2016 introduction).

Suggested Fix Add a maxNumLines (and/or cumulative-detail-size) parameter to SmtpResponseDecoder, incrementing per continuation line and throwing TooLongFrameException when exceeded — mirroring StompSubframeDecoder's maxNumHeaders. Provide a safe default (e.g., 128) via an overloaded constructor.

--- Reported by zx (Jace) — GitHub: @manus-use

Affected: - maven:io.netty:netty-codec-smtp affected >= 4.2.0.Final, <= 4.2.17.Final; fixed unknown - maven:io.netty:netty-codec-smtp affected >= 4.1.0.Final, <= 4.1.137.Final; fixed unknown

Fixed versions: see advisory

Advisory: https://github.com/netty/netty/security/advisories/GHSA-pq4x-537v-r54q

Affected Software

2 affected components
Netty netty-codec-smtp>=4.2.0.Final<=4.2.17.Final
Netty netty-codec-smtp>=4.1.0.Final<=4.1.137.Final

Event History

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

Frequently Asked Questions

1

Which systems are exposed to this denial-of-service condition?

Netty-based SMTP clients or MTAs that use io.netty.handler.codec.smtp.SmtpResponseDecoder are exposed when communicating with a malicious SMTP server or when an attacker can act as a man-in-the-middle for the SMTP connection.

2

What does an attacker need to do to trigger the issue?

The attacker must send SMTP continuation responses such as repeated "250-x\r\n" lines while withholding the space-separated terminating response line. This causes response details to remain accumulated across decoder invocations.

3

Does the decoder's maximum line-length setting prevent memory exhaustion?

No. The described maxLineLength limit applies to individual lines only; it does not cap the number of accumulated continuation lines or their total size.

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