Volver
2026/10/28
Node2Shell (CVE-2026-111497): qué sistemas están en riesgo y qué hacer ahora
Qué sistemas expone realmente CVE-2026-111497 en Brotli, la urgencia de cada caso y cómo parchear, reconstruir, reiniciar y mitigar ya.
Actualizado el 27 de octubre de 2026
CVE-2026-111497, apodada “Node2Shell” o “HTTP2Shell”, es un fallo de corrupción de memoria en el descompresor Brotli. Brotli es la compresión br que se usa en toda la web. El fallo está en las versiones 1.0.3 a 1.2.0 de la biblioteca Brotli de Google [1]. Node.js incluye esa biblioteca, y el proyecto Node.js calificó el problema como de severidad alta (High) para las ramas 22.x, 24.x y 26.x [2]. El mismo decodificador se distribuye dentro de paquetes de Python, bibliotecas del sistema Linux, aplicaciones de escritorio y herramientas para desarrolladores, por lo que la exposición real es mucho más amplia que “servidores Node.js”.
Este artículo está dirigido a los equipos que necesitan decidir rápidamente si están expuestos y qué hacer primero.
En resumen: si alguno de sus sistemas descomprime datos Brotli que provienen de alguien que usted no controla (un cliente en internet, un sitio web externo, el emisor de un webhook, un archivo subido), trátelo como urgente. Aplique el parche, reconstruya, reinicie y, mientras tanto, bloquee br.
Qué hace la vulnerabilidad
El decodificador gestiona mal un “block switch” malformado en el flujo comprimido. Interpreta el error como “necesito más datos de entrada” en lugar de “estos datos no son válidos”, y sigue añadiendo bytes a un pequeño búfer interno de tamaño fijo hasta escribir más allá de su final [2]. Un atacante que consiga que su aplicación descomprima un flujo Brotli manipulado puede corromper la memoria del proceso. Esto puede provocar:
- Una caída del proceso (denegación de servicio). Es el resultado más fiable.
- Fuga de memoria del proceso. Las respuestas o los logs podrían exponer fragmentos de secretos, tokens o datos de otros usuarios.
- Posible ejecución remota de código. Node.js incluye la RCE entre los impactos posibles [2]. La primera prueba de concepto pública solo logró ejecutar código contra una compilación debilitada a propósito, pero desde entonces unos investigadores han informado de ejecución de código, aunque poco fiable, contra una compilación oficial y sin modificar de Node.js 24.22.0 [3].
No se necesita autenticación: al atacante le basta con entregar bytes que lleguen al decodificador. Por eso la puntuación CVSS 4.0 es 9.2 (Critical) [1]. Así pues, la pregunta clave para cada sistema no es “¿usamos Brotli?”, sino “¿puede una parte no confiable hacer que descomprimamos Brotli?”
Casos de uso típicos y su riesgo
Caso 1: API expuestas a internet que aceptan cuerpos de solicitud comprimidos (máxima prioridad)
Algunos servidores de API en Node.js, BFF, gateways de API y endpoints de carga descomprimen los cuerpos de solicitud enviados con Content-Encoding: br. Otros hacen lo mismo mediante middleware. Riesgo: cualquier cliente anónimo en internet puede enviar un cuerpo manipulado. Los efectos van desde tumbar el servicio una y otra vez, un DoS barato, hasta filtrar memoria de un proceso que guarda datos de sesión y claves de API. Urgencia: emergencia. Aplique el parche hoy y, hasta entonces, bloquee los cuerpos de solicitud br en el perímetro.
Caso 2: Servicios que obtienen contenido del exterior (prioridad alta)
Los consumidores de webhooks, crawlers y scrapers, los servicios de vista previa de enlaces y RSS, las integraciones de pago o SaaS y los agentes de IA que navegan por la web realizan peticiones HTTP salientes. Muchos clientes HTTP envían Accept-Encoding: br y descomprimen la respuesta automáticamente. En Python, urllib3 y requests lo hacen siempre que esté instalado el paquete Brotli o brotlicffi, aunque su código nunca lo importe. aiohttp hace lo mismo, y httpx también cuando se instala con su extra brotli [4]. Riesgo: un servidor remoto malicioso, comprometido o suplantado puede atacar su backend a través de su respuesta. El atacante ni siquiera necesita llegar a su red: es usted quien lo llama. Urgencia: alta. Aplique primero el parche allí donde los destinos no sean totalmente de confianza.
Caso 3: Aplicaciones de escritorio, agentes de programación con IA y CLI con runtime integrado
Las aplicaciones Electron, las CLI basadas en Bun o Node y las herramientas de desarrollo con IA llevan su propia copia del runtime. Actualizar el paquete node del sistema no las corrige. Actualizar la aplicación en disco tampoco corrige las copias que ya se están ejecutando: los procesos de larga duración mantienen el runtime antiguo en memoria hasta que se reinician. Riesgo: estas herramientas suelen guardar credenciales y obtener contenido externo, lo que combina el Caso 2 con un proceso privilegiado. Urgencia: alta para las herramientas que obtienen contenido no confiable. Actualícelas y después reinícielas de verdad. Analizamos en detalle la trampa de “actualizado, pero sigue ejecutando el código antiguo” en HTTP2Shell: por qué actualizar un binario no corrige los procesos en ejecución.
Caso 4: Imágenes de contenedor y artefactos de CI/CD
Las imágenes construidas FROM node:22, node:24 o node:26 antes de la corrección siguen conteniendo el runtime vulnerable, aunque el host esté parcheado. Lo mismo ocurre con los wheels de Python empaquetados y las dependencias incluidas en el repositorio (vendored). Riesgo: el código vulnerable vuelve con cada despliegue y cada evento de autoescalado hasta que se reconstruye la imagen. Urgencia: alta para las imágenes que hay detrás de los Casos 1 y 2. Reconstruya en lugar de limitarse a reiniciar.
Caso 5: Bibliotecas del sistema Linux, fuentes y procesamiento de imágenes
Las distribuciones incluyen el decodificador como biblioteca compartida, por ejemplo libbrotli1 en Ubuntu/Debian. Lo usan curl y libcurl cuando la compresión está habilitada, FreeType para las fuentes web WOFF2 e, indirectamente, herramientas de imagen y documentos como Pillow. Riesgo: los sistemas que renderizan fuentes o documentos subidos por usuarios, o que obtienen contenido externo con curl --compressed, pueden recibir datos Brotli no confiables. Un servidor que nunca pasa datos externos a estas bibliotecas tiene una exposición práctica baja. Urgencia: media en la mayoría de los casos, pero alta para servicios de renderizado de documentos o de procesamiento de archivos subidos. Ubuntu ha publicado paquetes brotli corregidos para 22.04, 24.04, 26.04 y 26.10 [1]. Para RHEL, Oracle Linux y otras distribuciones, consulte el aviso de su proveedor sobre el paquete brotli en lugar de dar por supuesto un estado.
Caso 6: Sistemas solo internos con entradas de confianza (prioridad menor)
Algunos servicios solo descomprimen Brotli a partir de datos que usted mismo genera, como cachés internas o sus propios artefactos de compilación. El riesgo es menor, pero no nulo: un atacante que ya tenga un punto de apoyo puede usar el fallo para seguir avanzando. Urgencia: aplique el parche en el próximo ciclo habitual.
Qué hacer: pasos de respuesta
Paso 1: Localice dónde se decodifica Brotli (hoy)
- Node.js: compruebe
node -ven cada host, así como en cada imagen de contenedor y runner de CI. Busque en el código y la configuraciónbrotliDecompress,createBrotliDecompressy middleware de análisis de cuerpos que descomprimabr. - Runtimes integrados: haga un inventario de las aplicaciones Electron, CLI de Bun/Node y agentes de IA en uso, y anote la versión del runtime que integra cada una, no solo la versión de la aplicación.
- Python:
pip show Brotli brotlicffien cada entorno e imagen. Busquehttpx[brotli]y dependencias transitivas en los lockfiles y SBOM. - Paquetes del sistema operativo:
dpkg -l | grep brotliorpm -qa | grep brotli, y después compruebe qué procesos cargan realmente la biblioteca. - Priorice según los casos anteriores: todo lo que sea accesible con entradas no confiables (Casos 1, 2, 3 y 5 con archivos subidos) va primero.
Paso 2: Aplique parches a los componentes afectados
- Node.js: actualice a 22.23.4, 24.22.1 o 26.12.1 o posterior [2].
- Python:
Brotli>=1.2.1obrotlicffi>=1.2.1.0. Regenere los lockfiles [4]. - Brotli upstream / código C incluido en el repositorio: 1.0.10, 1.1.1 o 1.2.1, según la rama [1].
- Paquetes del sistema operativo: aplique la actualización de seguridad de su distribución para
brotli/libbrotli. - Aplicaciones de escritorio y agentes: actualice a versiones del proveedor que indiquen que incluyen el runtime corregido. Si un proveedor no ha publicado nada, considere la aplicación como no verificada, no como segura.
Paso 3: Reconstruya, vuelva a desplegar y reinicie
- Reconstruya las imágenes de contenedor a partir de imágenes base parcheadas y vuelva a desplegarlas. Reiniciar una imagen antigua no sirve.
- Reinicie todos los procesos de larga duración que tenían cargada la biblioteca vulnerable: servicios Node, workers, sesiones de agentes y todo lo que esté enlazado con la biblioteca del sistema. En trabajos con estado y agentes de IA, drene o traspase primero el trabajo para no perder eventos ni aprobaciones en cola.
Paso 4: Mitigue mientras aplica los parches
- Entrante: rechace los cuerpos de solicitud cuyo
Content-Encodingcontengabren el proxy inverso, el balanceador de carga o el WAF, antes de que ningún decodificador los procese. - Saliente: quitar
brdeAccept-Encodingno basta por sí solo, porque un servidor malicioso puede enviarbrde todos modos. Rechace también, o no decodifique, las respuestas que lleguen conContent-Encoding: br[4]. - Alternativa en Python: donde la actualización tenga que esperar, desinstale
Brotliybrotlicffipara que los clientes dejen de decodificarbr. Pruébelo antes, porque algunos servidores seguirán enviandobr.
Paso 5: Verifique y vigile posibles indicios de explotación
- Confirme la versión del runtime desde dentro del proceso o contenedor en ejecución, no solo desde el gestor de paquetes.
- Vuelva a escanear las imágenes y los SBOM para asegurarse de que no se sigue incorporando ninguna copia antigua de forma transitiva.
- Revise los logs recientes en busca de caídas inexplicables, fallos de segmentación o bucles de reinicio en servicios que manejan
br. Un conjunto de caídas procedentes de un único origen merece investigarse como un intento de ataque. - Si un servicio de alta exposición se cayó inesperadamente antes de ser parcheado, plantéese rotar los secretos que tenía ese proceso, ya que no se puede descartar una fuga de memoria.
Resumen
| Situación | Riesgo | Acción |
|---|---|---|
Una API pública decodifica cuerpos de solicitud br | Crítico | Parchear ya; bloquear br en el perímetro |
| El backend obtiene URL externas, webhooks o páginas web | Alto | Parchear ya; rechazar respuestas br |
| Aplicaciones Electron, agentes de IA o CLI con runtime integrado | Alto | Actualizar y reiniciar todas las instancias en ejecución |
| Imágenes de contenedor antiguas y artefactos de CI | Alto | Reconstruir a partir de bases parcheadas y volver a desplegar |
Biblioteca del sistema usada para archivos subidos, fuentes o curl --compressed | Medio–Alto | Aplicar la actualización del sistema operativo; reiniciar los servicios que la cargan |
| Solo datos internos de confianza | Bajo–Medio | Parchear en el próximo ciclo |
Parchear el paquete es solo la mitad del trabajo. La exposición solo desaparece cuando ningún proceso en ejecución, imagen o runtime integrado puede seguir decodificando Brotli no confiable con el código antiguo.
Global
Japan
Korea
China
Taiwan
Vietnam
Thailand
Indonesia
Portugal
France
Germany
Egypt
Russia