La familia 2Shell creció: después de PHP, investigadores demostraron ejecución remota de código en Node.js, con el build oficial como objetivo. El nombre que los investigadores le dieron: Node2Shell.
El caso es de Imperva. El objetivo era la imagen oficial de Node 24.22.0 para Linux arm64, sin depurador y sin build customizado, y el camino fue el decodificador Brotli que el runtime trae integrado, CVE-2026-111497. Node divulgó la falla y publicó la corrección el 21 de octubre, el mismo día del parche de emergencia de PHP, y la versión 24.22.1 rechaza los mismos datos que ejecutaban código en la anterior.
Cómo llega la aplicación al decodificador que nadie eligió
El decodificador Brotli existe en las líneas 22.x, 24.x y 26.x, y la aplicación lo alcanza por dos caminos que casi nadie lista en el inventario: leyendo una respuesta comprimida con Brotli mediante el fetch() nativo, o recibiendo un cuerpo de solicitud Brotli decodificado por middleware (Express 5 decodifica en los parsers de cuerpo, junto con gzip y deflate).
Un servidor Node puro, sin middleware, no decodifica por sí mismo. Pero quien usa framework, lo usa. Y el decodificador no fue elegido: vino integrado en el runtime, que es la definición de superficie de ataque que el inventario de paquetes declarados no ve.
La calibración honesta de la explotación
La primera prueba de concepto pública solo ejecutó código en un build debilitado a propósito, y en el build estándar el autor reportó crash y lectura limitada de memoria. La demostración de Imperva cruzó esa línea en el build oficial, pero necesitó varios intentos, y no hay explotación en la naturaleza reportada hasta el 22 de octubre.
La calibración importa porque define la prioridad: RCE demostrado en el build oficial con varios intentos es corrección de esta semana; prueba de concepto en build debilitado es corrección del ciclo. Las dos actualizan; la urgencia es diferente.
Qué hacer
- Actualizar a la 24.22.1, recordando que las imágenes de contenedores y los artefactos que integran el binario de Node necesitan su propia actualización, que el inventario de paquetes por sí solo no captura.
- Mapear las líneas fuera de soporte: la 20.x y anteriores no reciben la corrección y quedan expuestas.
- Limitar el tráfico Brotli no confiable en el borde mientras la actualización alcanza todo el parque: Imperva y Vercel ya publicaron reglas.
- Bajar el inventario hasta el binario: imagen de contenedor, decodificador integrado, versión de línea y fecha de fin de vida.
Conclusión
La semana dibujó el mapa: PHP, kernel y ahora el decodificador que nadie eligió instalar. El perímetro del servicio incluye lo que el runtime carga dentro, y el inventario que solo mira el paquete declarado no ve ese piso.
La familia 2Shell probablemente ganará más miembros, porque la técnica (el camino hasta un decodificador integrado con dato hostil) no es específica de runtime. La defensa que sobrevive a la familia es el inventario que baja hasta el binario y el borde que filtra lo que el runtime va a decodificar.