alta

CVE

CVE-2026-50010, CVE-2026-50011, CVE-2026-50020, CVE-2026-50560

CWE

CWE-347, CWE-444, CWE-400, CWE-770

Sistemas afectados

  • Consumidores de Maven de `io.netty:netty-handler` en Netty 4.1.x anterior a 4.1.135.Final o 4.2.x anterior a 4.2.15.Final cuando los contextos TLS del cliente llaman a `SslContextBuilder.forClient().trustManager(...)` con un `X509TrustManager` simple
  • Consumidores de Maven de `io.netty:netty-codec-http` en Netty 4.1.x anterior a 4.1.135.Final o 4.2.x anterior a 4.2.15.Final que analizan tráfico HTTP/1.1 controlado por el atacante
  • Consumidores de Maven de `io.netty:netty-codec-http2` en Netty 4.1.x anterior a 4.1.135.Final o 4.2.x anterior a 4.2.15.Final que actúan como servidores HTTP/2
  • Consumidores de Maven de `io.netty:netty-codec-redis` en Netty 4.1.x anterior a 4.1.135.Final o 4.2.x anterior a 4.2.15.Final que decodifican tráfico RESP no confiable
  • Servicios y frameworks de Java que importan estos módulos de Netty de forma transitiva a través de dependencias de nivel superior

El lanzamiento de seguridad de junio de Netty, 4.1.135.Final / 4.2.15.Final, es el tipo de actualización de infraestructura Java que puede parecer rutinaria hasta que se lee con detalle el conjunto de correcciones. Los problemas que llegaron a NVD el 12 de junio de 2026 no son casos extremos oscuros en extensiones sin uso. Se encuentran en las partes de Netty que terminan TLS, analizan HTTP/1.1, implementan HTTP/2 y agregan arrays RESP.

Eso importa porque muchos equipos no consumen Netty directamente. Lo heredan de forma transitiva a través de frameworks de nivel superior, gateways de API, stacks RPC o servidores de protocolo personalizados. Si tu proceso de AppSec solo vigila las notas de lanzamiento del framework de nivel superior y no los módulos subyacentes io.netty:*, este es el tipo de tren de seguridad que puede pasar desapercibido.

Qué está afectado

Los cuatro problemas de mayor relevancia de la ventana de publicación de NVD de junio se corresponden claramente con cuatro módulos distintos de Netty:

CVECoordenada MavenComportamiento vulnerableCorregido en
CVE-2026-50010io.netty:netty-handlerLa ruta de trust manager personalizado del cliente puede desactivar silenciosamente la verificación del nombre de host4.1.135.Final, 4.2.15.Final
CVE-2026-50020io.netty:netty-codec-httpEl parser de HTTP/1.1 acepta bytes de control iniciales más allá de CRLF y puede generar desacuerdo sobre el límite de la solicitud4.1.135.Final, 4.2.15.Final
CVE-2026-50011io.netty:netty-codec-redisLa cabecera de array de Redis puede forzar una preasignación de tamaño controlado por el atacante antes de que existan los mensajes hijos4.1.135.Final, 4.2.15.Final
CVE-2026-50560io.netty:netty-codec-http2El servidor puede verse forzado a un fallo de escritura de respuesta al respetar el límite de lista de cabeceras anunciado por un cliente hostil4.1.135.Final, 4.2.15.Final

Las notas de lanzamiento muestran que estos cuatro fueron solo parte de un tren de seguridad más amplio. El mismo lanzamiento también corrigió problemas adyacentes en el handler, Redis, DNS, HAProxy y HTTP/2 de Netty, como CVE-2026-45416, CVE-2026-47244, CVE-2026-48043, CVE-2026-44250, CVE-2026-44890 y CVE-2026-48006. Aunque un CVE específico no se aplique a tu despliegue, los equipos deberían revisar todo el lanzamiento en lugar de elegir un único aviso.

CVE-2026-50010: un trust manager personalizado puede desactivar la verificación del nombre de host

Este es el problema con mayor probabilidad de sorprender a desarrolladores Java experimentados porque rompe una suposición de seguridad en lugar de un parser. La descripción de NVD es precisa: un X509TrustManager simple proporcionado por el llamador se estaba envolviendo en un X509ExtendedTrustManager, lo que accidentalmente impedía que envoltorios posteriores añadieran la identificación de endpoint.

Antes de la corrección, la ruta relevante en SimpleTrustManagerFactory tenía este aspecto:

if (tm instanceof X509TrustManager && !(tm instanceof X509ExtendedTrustManager)) {
  trustManagers[i] = new X509TrustManagerWrapper((X509TrustManager) tm);
}

El problema no es solo el envoltorio en sí. Una vez que el objeto ya es un X509ExtendedTrustManager, ni la ruta interna de envoltorio de trust manager del JDK ni el propio envoltorio de OpenSSL de Netty tienen motivo para volver a envolverlo y aplicar la verificación de nombre de host. Eso significa que código con esta forma puede perder la protección que los desarrolladores creen tener:

SslContext sslContext = SslContextBuilder
    .forClient()
    .trustManager(somePlainX509TrustManager)
    .build();

Netty 4.2 ya establece por defecto endpointIdentificationAlgorithm en "HTTPS", pero CVE-2026-50010 muestra que un gancho de trust manager personalizado bien intencionado todavía puede anular el paso de verificación de nombre de host.

La corrección es reveladora porque elimina el envoltorio automático de la factory genérica de trust manager, manteniendo el comportamiento inseguro explícito aislado en la ruta intencionadamente peligrosa:

// eliminado de SimpleTrustManagerFactory
// se mantiene solo donde Netty desactiva intencionadamente la verificación

En otras palabras, InsecureTrustManagerFactory sigue siendo insegura a propósito, pero la ruta ordinaria de SimpleTrustManagerFactory deja de suprimir silenciosamente la verificación de nombre de host para llamadores que nunca pidieron eso.

CVE-2026-50020: Netty era más permisivo de lo que permite el RFC 9112

El problema de HTTP/1.1 es un clásico de desacuerdo entre parsers. El RFC 9112 permite que los servidores ignoren líneas CRLF iniciales vacías antes de la línea de solicitud como una concesión estrecha de interoperabilidad. El HttpObjectDecoder de Netty iba más allá y saltaba cualquier carácter de control ISO antes de la línea inicial.

La corrección muestra el estado del parser volviéndose más explícito:

private enum State {
  SKIP_INITIAL_LINE_CHARS,
  READ_INITIAL,
  READ_HEADER,
  ...
}

Y el escaneo real de bytes ahora distingue “ignorar basura de control ordinaria” de “solo tolerar CRLF cuando las comprobaciones estrictas están activadas”:

final int firstNonLineIndex = buffer.forEachByte(
    readerIndex,
    maxToSkip,
    strictCRLFCheck == null ? SKIP_CONTROL_CHARS_BYTES : ByteProcessor.FIND_NON_CRLF
);

También hay una nueva prueba de regresión que hace muy concreto el límite de seguridad:

buf.writeByte(0x00);   // NUL
buf.writeByte(0x01);   // SOH
buf.writeCharSequence("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n", US_ASCII);

Esa solicitud ahora se rechaza en lugar de normalizarse silenciosamente.

Por qué importa a los equipos de AppSec: el request smuggling y la confusión de límites de solicitud no requieren un fallo en tu lógica de negocio. Solo requieren que un componente frontend y un componente backend no coincidan sobre dónde empieza una solicitud o qué bytes son ignorables. Si un proxy o balanceador de carga conserva bytes que Netty descarta, la propia laxitud del parser se convierte en la primitiva.

CVE-2026-50011: las cabeceras de array RESP no deberían controlar la asignación de heap

El problema de Redis es un ejemplo claro de “nunca preasignar a partir de una longitud declarada por el atacante”. NVD describe el fallo original de forma sencilla: RedisArrayAggregator usaba el recuento de elementos de array declarado en la cabecera RESP para dimensionar un ArrayList antes de que existieran siquiera los mensajes hijos en el cable.

La corrección añade un límite configurable:

public RedisArrayAggregator(int maxElements) {
  this.maxElements = ObjectUtil.checkPositive(maxElements, "maxElements");
}

if (header.length() > maxElements) {
  throw new CodecException("this codec doesn't support longer length than " + maxElements);
}

Netty también introdujo un límite predeterminado respaldado por propiedad:

static final String PROP_REDIS_MAX_ARRAY_LENGTH =
    "io.netty.handler.codec.redis.maxArrayLength";
static final int REDIS_MAX_ARRAY_LENGTH =
    SystemPropertyUtil.getInt(PROP_REDIS_MAX_ARRAY_LENGTH, 1000000);

Ese es un paso de fortalecimiento significativo porque la forma vulnerable era barata para un atacante. Un frame RESP pequeño podía declarar una longitud de array enorme y forzar al JVM a una asignación de array de respaldo grande de inmediato, mucho antes de que existiera un árbol de mensajes legítimo.

Este módulo merece atención adicional porque el mismo lanzamiento corrigió varios otros problemas de agotamiento de recursos en el codec de Redis. Si expones el análisis del protocolo Redis a pares no confiables, o usas el codec de Redis de Netty dentro de un proxy, gateway o servicio personalizado, actualizar solo por CVE-2026-50011 subestima el riesgo real.

CVE-2026-50560: un cliente HTTP/2 no debería dictar el presupuesto de respuesta del servidor

El problema de HTTP/2 es sutil pero operativamente importante. SETTINGS_MAX_HEADER_LIST_SIZE es advisorio desde la perspectiva del cliente: indica al servidor qué está dispuesto a recibir el cliente, no lo que el servidor debe limitar para su propia lógica de generación de respuesta.

Antes de la corrección, un cliente hostil podía anunciar un valor diminuto y provocar que la ruta de escritura de cabecera de respuesta del servidor fallara. El parche cambia exactamente ese punto de decisión:

Long maxHeaderListSize = settings.maxHeaderListSize();
if (maxHeaderListSize != null && !connection.isServer()) {
  outboundHeaderConfig.maxHeaderListSize(maxHeaderListSize);
}

La nueva prueba de regresión es útil porque demuestra la forma del exploit en pocas líneas:

http2Client.encoder().writeSettings(
    ctx(),
    new Http2Settings().maxHeaderListSize(2),
    newPromise()
);

Luego el servidor intenta emitir una respuesta :status normal y debe tener éxito aunque el cliente afirmara que solo aceptaría dos bytes de cabeceras. El propio PR de Netty explica bien el impacto: esto es “similar a HTTP/2 Rapid Reset, pero con una firma diferente en el cable.”

Si terminas HTTP/2 directamente en Netty, especialmente en roles de gateway o proxy, esa es la forma correcta de pensar sobre este fallo. No es un capricho de pureza de protocolo. Es una primitiva barata de recursos remotos y generación de errores.

Delimitando tu exposición

Empieza por identificar si los módulos de Netty afectados están presentes:

mvn dependency:tree -Dincludes=io.netty:netty-handler,io.netty:netty-codec-http,io.netty:netty-codec-http2,io.netty:netty-codec-redis
./gradlew dependencies --configuration runtimeClasspath | rg "io\\.netty:(netty-handler|netty-codec-http2?|netty-codec-redis)"

Luego busca las rutas de código que hacen alcanzable cada problema:

rg -n "SslContextBuilder\\.forClient\\(|trustManager\\(" src
rg -n "HttpRequestDecoder|HttpServerCodec|HttpClientCodec|HttpObjectDecoder" src
rg -n "RedisArrayAggregator|RedisDecoder|RedisBulkStringAggregator" src
rg -n "Http2Settings|DefaultHttp2ConnectionEncoder|Http2FrameCodec" src

El problema de verificación de nombre de host es el menos obvio de encontrar solo mediante comportamiento en tiempo de ejecución. Estás buscando contextos TLS de cliente de Netty que pasan un trust manager personalizado, especialmente SDKs internos o bibliotecas de transporte compartidas que querían material de confianza personalizado pero no pretendían desactivar la comprobación de endpoint.

Remediación

Actualiza todos los artefactos de Netty en la línea afectada juntos:

  • Netty 4.1.x -> 4.1.135.Final
  • Netty 4.2.x -> 4.2.15.Final

Evita actualizaciones parciales entre módulos io.netty:*. Las correcciones de seguridad de Netty a menudo llegan como cambios coordinados entre superficies de handler, codec y pruebas, y las versiones mezcladas son una buena forma de cambiar una vulnerabilidad conocida por incompatibilidad en tiempo de ejecución.

Para la priorización:

  1. corrige primero cualquier ruta TLS de cliente personalizada que use trustManager(...);
  2. luego parchea los servicios Netty orientados a HTTP, especialmente los que están detrás de proxies o hablan HTTP/2 directamente;
  3. después parchea los consumidores del protocolo Redis y revisa si deberían analizar tráfico no confiable en primer lugar.

La lección más amplia de este lanzamiento es que las bibliotecas de transporte maduras todavía definen la superficie de ataque real de tu aplicación. El envoltorio TLS, el análisis de la primera línea, la aplicación de límites de cabecera y la preasignación del decodificador no son “internos del framework” una vez que pares no confiables pueden alcanzarlos. Son parte del límite de seguridad de la aplicación, y este lanzamiento de Netty de junio corrigió cuatro lugares donde ese límite era demasiado permisivo.

De la investigación a la remediación

Comprueba si este patrón existe en tu código

Convierte esta investigación en un flujo de remediación. Analiza dependencias y manifiestos para detectar riesgos similares en la cadena de suministro y prioriza las correcciones con contexto de alcanzabilidad.

Referencias