Mittel

Netty: HttpObjectDecoder skips arbitrary initial control characters when only initial CRLF characters are permitted

  • Veröffentlicht: 15.06.2026
  • Aktualisiert: 11.10.2026 13:20

Summary

Before reading the first request-line, HttpObjectDecoder skips every byte for which Character.isISOControl(b) is true (0x00–0x1F and 0x7F) as well as all whitespace. RFC 9112 §2.2 only asks servers to ignore empty CRLF lines preceding the request-line — a carefully scoped robustness allowance intended to handle HTTP/1.0 POST workarounds. Silently absorbing NUL bytes, SOH, STX, and other non-CRLF control characters goes significantly beyond this, and can be exploited for request-boundary confusion in pipelined or multiplexed transports where a front-end component treats those bytes differently.

Affected Code

File Lines Role
codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java 1298–1313 ISO_CONTROL_OR_WHITESPACE static initialiser — marks all ISO control chars
codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java 1307–1313 SKIP_CONTROL_CHARS_BYTES ByteProcessor — skips the entire set
codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java 1275–1289 LineParser.skipControlChars — advances readerIndex past all matching bytes

Specification Analysis

RFC 9112 §2.2 — Message Parsing

In the interest of robustness, a server that is expecting to receive and parse a request-line SHOULD ignore at least one empty line (CRLF) received prior to the request-line.

An HTTP/1.1 user agent MUST NOT preface or follow a request with an extra CRLF.

Deviation

The RFC names a single permitted exception: an empty line (bare CRLF, i.e. the two-byte sequence \r\n). The ISO_CONTROL_OR_WHITESPACE table is initialised as:

java
for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
    ISO_CONTROL_OR_WHITESPACE[128 + b] =
        Character.isISOControl(b) || isWhitespace(b);
}

Character.isISOControl returns true for 0x00–0x1F and 0x7F. This includes NUL (0x00), SOH (0x01), STX (0x02), BEL (0x07), DEL (0x7F), and every other non-CRLF control character. The SKIP_CONTROL_CHARS state runs this scan unconditionally before the first READ_INITIAL, meaning any sequence of such bytes prepended to a request is silently consumed.

A load balancer or TLS terminator that does not perform the same scan sees a different message boundary than Netty does, which is the basis of a request-desync / smuggling attack.

Suggested Unit Test

Add to HttpRequestDecoderTest.java.

java
@Test
public void testNonCrlfControlBytesPrecedingRequestLineAreRejected() {
    // RFC 9112 §2.2: servers SHOULD ignore "at least one empty line (CRLF)" before the
    // request-line.  Non-CRLF control bytes are not part of this robustness allowance
    // and must not be silently swallowed.
    EmbeddedChannel channel = new EmbeddedChannel(new HttpRequestDecoder());

    ByteBuf buf = Unpooled.buffer();
    buf.writeByte(0x00);   // NUL  — not an empty CRLF line
    buf.writeByte(0x01);   // SOH  — not an empty CRLF line
    buf.writeCharSequence(
            "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n",
            CharsetUtil.US_ASCII);

    channel.writeInbound(buf);
    HttpRequest req = channel.readInbound();

    // Current behaviour: NUL and SOH are in ISO_CONTROL_OR_WHITESPACE, so they are
    // silently skipped; the request decodes successfully and isFailure() == false.
    //
    // RFC-correct behaviour: only empty CRLF lines should be ignored; NUL/SOH must
    // cause a parse error — isFailure() == true.
    assertTrue(
            req.decoderResult().isFailure(),
            "Non-CRLF control bytes before the request-line must not be silently skipped " +
            "(RFC 9112 §2.2 allows only empty CRLF lines)");

    assertFalse(channel.finish());
}

Current behaviour (unfixed): skipControlChars advances past 0x00 and 0x01 because both are in ISO_CONTROL_OR_WHITESPACE; the request parses normally, isFailure() is false → test fails.

Expected behaviour after fix: only CRLF empty lines are tolerated; non-CRLF control bytes produce an error, isFailure() is true → test passes.

Betroffene Software

Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.

PlattformPaketAnfällige VersionenBehoben in
Java / Kotlin (Maven) io.netty:netty-codec-http >= 4.2.0.Final, < 4.2.15.Final, < 4.1.135.Final 4.2.15.Final, 4.1.135.Final

Verweise

CVSS-Wert 5.3/10
CVSS-Vektor
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Schwäche (CWE)
CWE-444
Plattform
Java / Kotlin (Maven)
Paket
io.netty:netty-codec-http
Veröffentlicht
15.06.2026
Aktualisiert
11.10.2026 13:20

Quellen und Lizenzen

OSV / GitHub Advisory Database - GHSA-hvcg-qmg6-jm4c - CC BY 4.0

Schwachstellenhistorie: io.netty:netty-codec-http

Alle veröffentlichten Schwachstellen dieses Pakets (Java / Kotlin (Maven)), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.

Alle (24) im Archiv
Einträge insgesamt
24
Erste → letzte
02.2020 08.2026
Ohne Fix
0
In Angriffen ausgenutzt
0

Verteilung nach Schweregrad

  • Kritisch 1
  • Hoch 6
  • Mittel 16
  • Niedrig 1

Veröffentlichungen pro Jahr

  1. 2020: 1
  2. 2021: 2
  3. 2022: 2
  4. 2023: 0
  5. 2024: 1
  6. 2025: 2
  7. 2026: 16
Schweregrad:
  1. Hoch CVE-2026-56745 >= 4.2.0.Final, < 4.2.16.Final, >= 4.1.0.Final, < 4.1.136.Final 4.2.16.Final, 4.1.136.Final
  2. Hoch · 7.5 CVE-2026-55833 >= 4.2.0.Final, < 4.2.16.Final, >= 4.1.0.Final, < 4.1.136.Final 4.2.16.Final, 4.1.136.Final
  3. Hoch · 7.5 CVE-2026-55831 >= 4.2.0.Final, < 4.2.16.Final, >= 4.1.0.Final, < 4.1.136.Final 4.2.16.Final, 4.1.136.Final
  4. Netty: HttpObjectDecoder skips arbitrary initial control characters when only initial CRLF characters are permitted dieser Eintrag
    Mittel · 5.3 CVE-2026-50020 >= 4.2.0.Final, < 4.2.15.Final, < 4.1.135.Final 4.2.15.Final, 4.1.135.Final
  5. Hoch · 7.5 CVE-2026-42587 >= 4.2.0.Alpha1, < 4.2.13.Final, < 4.1.133.Final 4.2.13.Final, 4.1.133.Final
  6. Hoch · 7.3 CVE-2026-42584 >= 4.2.0.Alpha1, < 4.2.13.Final, < 4.1.133.Final 4.2.13.Final, 4.1.133.Final
  7. Hoch · 7.5 CVE-2026-33870 < 4.1.132.Final, >= 4.2.0.Alpha1, < 4.2.10.Final 4.1.132.Final, 4.2.10.Final
  8. Kritisch · 9.1 CVE-2019-20444 < 4.1.44 4.1.44

Erkennen Sie Schwachstellen in Ihrer Anwendung

Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.

Anwendung verbinden
DockRay Newsletter

Anwendungssicherheit in Ihrem Postfach

Wichtige Schwachstellen, konkrete Empfehlungen und praktische Tipps für Ihre Anwendungen. Wählen Sie Ihre Technologien und verfolgen Sie, was für Ihr Projekt relevant ist.

  • Eine tägliche Zusammenfassung neuer Schwachstellen, auch kritischer.
  • Benachrichtigungen über wichtige Updates.
  • Praktische Tipps zur Sicherheit und Überwachung von Anwendungen.

Leer lassen, um Meldungen zu allen Technologien zu erhalten.

Kostenlos anmelden. In jeder E-Mail mit einem Klick abmelden.