Media

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

  • Publicada: 15.06.2026
  • Actualizado: 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.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
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

Referencias

Puntuación CVSS 5.3/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Debilidad (CWE)
CWE-444
Plataforma
Java / Kotlin (Maven)
Paquete
io.netty:netty-codec-http
Publicada
15.06.2026
Actualizado
11.10.2026 13:20

Fuentes y licencias

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

Historial de vulnerabilidades: io.netty:netty-codec-http

Todas las vulnerabilidades publicadas de este paquete (Java / Kotlin (Maven)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (24) en el archivo
Entradas en total
24
Primera → última
02.2020 08.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Crítica 1
  • Alta 6
  • Media 16
  • Baja 1

Divulgaciones por año

  1. 2020: 1
  2. 2021: 2
  3. 2022: 2
  4. 2023: 0
  5. 2024: 1
  6. 2025: 2
  7. 2026: 16
Gravedad:
  1. Alta 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. Alta · 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. Alta · 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 esta entrada
    Media · 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. Alta · 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. Alta · 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. Alta · 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. Crítica · 9.1 CVE-2019-20444 < 4.1.44 4.1.44

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.