Un fallo en el decodificador Brotli permite a un servidor malicioso tomar Node.js y Python
Un fallo en el decodificador Brotli de Google permite que un flujo comprimido manipulado escriba más allá del final de un búfer en memoria. Registrado como CVE-2026-111497 y valorado con 9,2 sobre 10 en el aviso de GitHub, afecta a las versiones 1.0.3 a 1.2.0 de Brotli. Brotli comprime buena parte del tráfico web actual, así que el problema va mucho más allá de una biblioteca: Node.js, Bun, Envoy, Istio y los paquetes de Python que requests y aiohttp usan por su cuenta incluyen o cargan el código vulnerable. Los parches salieron entre el 21 y el 23 de octubre.
Qué falla
Un flujo Brotli se divide en bloques, y el decodificador cambia entre tipos de bloque a medida que lee. Según el aviso de Node.js, un cambio de bloque no válido se trataba como una necesidad temporal de más datos en lugar de como un error de formato. El decodificador seguía añadiendo bytes del atacante a un búfer interno de ocho bytes y escribía más allá de su final. Según lo que se sobrescriba, el resultado es un cierre inesperado, una fuga de memoria del proceso o la ejecución remota de código.
El fallo lo comunicaron a Node.js Khai Tran y Sylvie Mayer, de OpenAI Codex Security. Google publicó las versiones corregidas 1.0.10, 1.1.1 y 1.2.1 de Brotli, y Node.js lanzó 22.23.4, 24.22.1 y 26.12.1 el 21 de octubre. Node.js 20 y otras ramas sin soporte no recibirán parche.
El ataque funciona en ambos sentidos
El decodificador actúa allí donde llegan datos comprimidos, así que cualquiera de los dos extremos de una conexión puede ser el objetivo. Un servidor malicioso puede atacar a un cliente: el fetch() integrado en Node descomprime automáticamente las respuestas Brotli, igual que las bibliotecas de Python requests, urllib3 y aiohttp cuando hay un paquete Brotli instalado. La aplicación ni siquiera tiene que importarlo. Webhooks, vistas previas de enlaces, rastreadores y funciones de «importar desde una URL» descargan contenido de servidores ajenos a todas horas.
En sentido contrario, un cliente puede atacar a un servidor que descomprime el cuerpo de las peticiones. Express 5.0.0 a 5.3.0 y body-parser 2.0.0 a 2.3.0 descomprimen Brotli en sus parsers raw() y json(). El Imperva Red Team ejecutó su propio código en la imagen oficial de Node.js 24.22.0 por ambas vías: una respuesta descargada y el cuerpo de una petición a Express. Necesitó varios intentos, e Imperva no ha publicado el exploit.
Hasta dónde llega
El fallo está en el decodificador de referencia en C de Google, y muchos proyectos incluyen su propia copia. Un recuento publicado en broccoli2shell.com recoge parches para Bun 1.4.4, Envoy, Istio, Chromium, Firefox, ngx_brotli y los paquetes de Python Brotli 1.2.1 y brotlicffi 1.2.1.0. A 24 de octubre seguía listando copias sin parchear en .NET, las extensiones brotli de PHP y Ruby, DuckDB, ClickHouse, Apache Arrow, la biblioteca JPEG XL, forks de 7-Zip y MuPDF.
Las distribuciones de Linux parchean por separado la biblioteca compartida libbrotli. Debian, por ejemplo, ya lo hizo en sus actualizaciones de seguridad para bookworm y trixie. El 22 de octubre apareció en GitHub una prueba de concepto pública, aunque según los informes solo logra ejecutar código en una compilación debilitada a propósito. Hasta entonces no se habían registrado ataques reales.
Qué revisar
- Navegadores: Chrome, Edge y Firefox descomprimen Brotli en casi todas las páginas. Instala la última actualización y reinicia el navegador.
- Node.js y Bun: ejecuta node --version. Todo lo que esté por debajo de 22.23.4, 24.22.1 o 26.12.1, o en una rama sin soporte como la 20, necesita actualizarse. Bun debe ser 1.4.4 o posterior.
- Python: ejecuta pip show Brotli brotlicffi. Si alguno es anterior a 1.2.1, actualízalo o desinstálalo, y requests volverá a gzip.
- Servidores: instala la actualización de libbrotli de tu distribución y reinicia todos los servicios que la cargan. Un proceso en marcha mantiene el decodificador antiguo en memoria hasta que se reinicia.
Este último punto se pasa por alto con facilidad. El gestor de paquetes puede instalar el parche de madrugada mientras PHP, Python y otros procesos de larga duración siguen semanas con la copia vieja. Para quien administra su propio servidor, es el segundo «actualizar y reiniciar» del mes, después de los fallos de NGINX.