Brotli CVE-2026-111497: parchea apps Node.js, Bun y Python

Brotli CVE-2026-111497: parchea apps Node.js, Bun y Python

Brotli CVE-2026-111497: parchea apps Node.js, Bun y Python

CVE-2026-111497 es un fallo de corrupción de memoria en el decodificador Brotli de Google, el código C que descomprime los datos con Content-Encoding: br. Unos datos comprimidos manipulados escriben más allá del final de un búfer, lo que puede tumbar el programa, filtrar memoria o ejecutar código del atacante. Node.js, Bun, los paquetes de Python Brotli y brotlicffi y Envoy incluyen cada uno su propia copia de ese decodificador, así que hay que actualizar cada uno por separado. Esta guía explica cuándo una aplicación está realmente expuesta, cómo revisar un servidor con un solo comando y cómo desplegar la corrección sin olvidar ningún contenedor.

Qué tan grave es

  • Google le asigna 9.2 (critical) en CVSS 4.0, Node.js la califica como high y Red Hat con 8.1.
  • Los investigadores de Imperva ejecutaron su propio código en un Node.js 24.22.0 sin parchear sobre Linux ARM64, tanto a través de una respuesta obtenida con fetch como del cuerpo de una petición en Express. El exploit no es público.
  • La evaluación de CISA del 23 de octubre no registró explotación activa, y no existe una prueba de concepto pública fiable.
  • El fallo funciona en ambos sentidos: un servidor que descomprime entradas comprimidas puede ser atacado por un cliente, y un cliente que descomprime respuestas comprimidas puede ser atacado por un servidor.

La corrección se integró en el código fuente de Brotli el 27 de febrero, pero ninguna versión de Brotli la incluyó hasta el 21 de octubre, por eso todos los runtimes parcheados aparecieron la misma semana.

¿Estás expuesto?

Solo corre riesgo el código que decodifica datos Brotli controlados por otra persona:

  • Node.js y Bun - el fetch() integrado al leer una respuesta enviada con Content-Encoding: br, las llamadas Brotli de node:zlib sobre datos no confiables y los parsers de cuerpo que descomprimen subidas en Brotli (Express 5, body-parser 2). Un servidor HTTP de Node.js sin más no decodifica los cuerpos de las peticiones por sí solo.
  • Python - basta con tener instalado el paquete Brotli o brotlicffi: requests, urllib3, httpx y aiohttp decodifican entonces las respuestas Brotli por su cuenta, aunque tu código nunca importe Brotli.
  • Envoy e Istio - solo si hay configurado un filtro de descompresión Brotli.

Cualquier servicio que llame a APIs de terceros, webhooks o proveedores de pago, o que haga scraping de páginas, ejecuta fetch() contra servidores que no controlas. Quitar br de Accept-Encoding no es una solución: un servidor puede enviar Brotli de todos modos.

Software Afectado Corregido en
Node.js 22.x, 24.x, 26.x antes de la corrección; 20.x y anteriores (fin de soporte) 22.23.4, 24.22.1, 26.12.1
Bun 1.4.3 y anteriores 1.4.4
Python Brotli 1.2.0 y anteriores 1.2.1
Python brotlicffi 1.2.0.x y anteriores 1.2.1.0
Google Brotli (biblioteca C) 1.0.3 - 1.2.0 1.0.10, 1.1.1, 1.2.1
Envoy 1.39.2, 1.38.5, 1.37.7, 1.36.11 1.40.0, 1.39.3, 1.38.6, 1.37.8, 1.36.12
Istio 1.31.0 - 1.31.1, 1.30.0 - 1.30.5, 1.29.0 - 1.29.8 1.31.2, 1.30.6, 1.29.9

Revisa un servidor con un solo comando

Este script de shell POSIX revisa Bun, Node.js y Python en la máquina (o dentro de un contenedor) e indica cuáles son anteriores a la corrección. Guárdalo como brotli-check.sh:

#!/bin/sh
# CVE-2026-111497 (Brotli decoder): which runtimes on this host are older than the fixes?
ver_lt() { [ "$1" = "$2" ] && return 1; [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]; }
if command -v bun >/dev/null 2>&1; then
  v=$(bun --version)
  if ver_lt "$v" 1.4.4; then echo "bun $v: VULNERABLE, upgrade to 1.4.4+"; else echo "bun $v: fixed"; fi
fi
if command -v node >/dev/null 2>&1; then
  v=$(node -p "process.versions.bun ? '' : process.versions.node")
  if [ -z "$v" ]; then echo "node: this is Bun's node shim, see the bun line"; else major=${v%%.*}
  case $major in
    22) fix=22.23.4 ;; 24) fix=24.22.1 ;; 26) fix=26.12.1 ;;
    *) fix= ;;
  esac
  if [ -z "$fix" ]; then echo "node $v: no fixed release for this line, move to 22, 24 or 26"
  elif ver_lt "$v" "$fix"; then echo "node $v: VULNERABLE, upgrade to $fix+"
  else echo "node $v: fixed"; fi
  fi
fi
for py in python3 python; do
  command -v $py >/dev/null 2>&1 || continue
  $py - <<'PY'
from importlib import metadata
for pkg, fix in (("Brotli", "1.2.1"), ("brotlicffi", "1.2.1.0")):
    try:
        v = metadata.version(pkg)
    except metadata.PackageNotFoundError:
        print(f"python {pkg}: not installed")
        continue
    a = [int(x) for x in v.split(".") if x.isdigit()]
    b = [int(x) for x in fix.split(".")]
    print(f"python {pkg} {v}: {'VULNERABLE, upgrade to ' + fix + '+' if a < b else 'fixed'}")
PY
  break
done
sh brotli-check.sh
docker exec my-app sh -s < brotli-check.sh   # the same check inside a running container

Salida comprobada el 2026-10-24 (un portátil de desarrollo y después imágenes oficiales de Docker):

bun 1.4.1: VULNERABLE, upgrade to 1.4.4+
node 26.6.0: VULNERABLE, upgrade to 26.12.1+
python Brotli: not installed
python brotlicffi: not installed
bun 1.4.4: fixed
node: this is Bun's node shim, see the bun line
node 22.23.4: fixed
node 16.20.2: no fixed release for this line, move to 22, 24 or 26
python Brotli 1.1.0: VULNERABLE, upgrade to 1.2.1+
python brotlicffi: not installed

Ejecútalo en cada contenedor, no solo en el host: el Node.js del host no dice nada del que va empaquetado en una imagen.

Cómo desplegar la corrección

  1. Encuentra cada copia. Las imágenes son lo que más se olvida. Lista lo que ejecutas: docker ps --format '{{.Image}}' y luego las líneas FROM de tus Dockerfiles. Una etiqueta como node:22 u oven/bun:alpine solo avanza cuando haces pull; una etiqueta fijada como oven/bun:1.4.1-slim no avanza nunca.
  2. Actualiza el runtime. Sube las etiquetas fijadas (oven/bun:1.4.4-slim, node:22.23.4-alpine), ejecuta bun upgrade y actualiza los paquetes de Node.js en los hosts, y en los entornos Python pip install -U "Brotli>=1.2.1" (o brotlicffi>=1.2.1.0). Si una aplicación Python no necesita Brotli, pip uninstall Brotli brotlicffi también cierra la vía: los clientes HTTP pasan a usar gzip y deflate.
  3. Reconstruye y sustituye. docker compose build --pull && docker compose up -d. Un proceso en marcha conserva el decodificador antiguo hasta que se reinicia, así que reinicia también los servicios en los hosts.
  4. Verifica. Vuelve a ejecutar el script dentro de cada contenedor (docker exec <name> bun --version es la versión rápida). Los lockfiles con --frozen-lockfile pueden hacer fallar la reconstrucción tras subir dependencias: haz commit del lockfile actualizado junto con package.json.
  5. ¿Aún no puedes actualizar? Rechaza en el proxy las peticiones con Content-Encoding: br antes de que nada decodifique el cuerpo, y evita descargar datos de hosts no confiables. Vercel señala que las reglas de firewall no cubren las respuestas que tu propio código obtiene de otros servidores - solo la actualización lo hace.

Para un stack Node.js en una VM consulta Servidor cloud para Node.js, para Python Servidor cloud para Python y Flask y para imágenes que se reconstruyen sin problemas Servidor cloud para Docker Swarm.

Qué hicimos nosotros

A los pocos días de las correcciones pasamos a 1.4.4 todos los servicios de DCXV que funcionan con Bun: las imágenes base fijadas pasaron a etiquetas corregidas y todas las imágenes se reconstruyeron con un pull nuevo. Nuestros componentes Node.js no decodifican cuerpos Brotli y nuestros proxies no tienen descompresión Brotli. Los servidores de los clientes los gestionan sus propietarios: si ejecutas Node.js, Bun o Python en un servidor cloud de DCXV, lanza hoy la comprobación de arriba o pregúntanos por la administración gestionada de servidores.

Fuentes (consultadas el 2026-10-24): las versiones de seguridad de Node.js de octubre de 2026 (22.23.4, 24.22.1, 26.12.1), la versión Bun 1.4.4, la evaluación de CISA del 23 de octubre de 2026 y la investigación de Imperva.

PHP2Shell: comprueba y parchea el RCE de PHP en tu servidor
clouddedicatedhosting

PHP2Shell: comprueba y parchea el RCE de PHP en tu servidor

PHP2Shell (CVE-2026-109618, CVE-2026-109619) permite que una petición sin autenticar ejecute código en PHP. Versiones corregidas, script probado, ajustes de php.ini y plan.

Brotli CVE-2026-111497: parchea apps Node.js, Bun y Python
cloudnetworkinginfrastructure

Brotli CVE-2026-111497: parchea apps Node.js, Bun y Python

Un fallo del decodificador Brotli (CVE-2026-111497) ejecuta código vía fetch() en Node.js y Bun o clientes HTTP de Python. Versiones corregidas, script probado y rebuild.

Cómo dimensionar un servidor cloud para SaaS: CPU, RAM, NVMe
cloudinfrastructurepricing

Cómo dimensionar un servidor cloud para SaaS: CPU, RAM, NVMe

Dimensiona un servidor cloud para SaaS con Docker y Node.js: presupuesto de memoria, límites de CPU, NVMe y copias, prueba de carga k6, precio mensual y hoja.

Agentes de código con IA en VPS de la UE: setup reforzado
aicloudhosting

Agentes de código con IA en VPS de la UE: setup reforzado

Aloja agentes de código con IA en un VPS de la UE con límites: espacios desechables, salida permitida, tokens acotados, topes, código probado, riesgos y coste.

Corregir la geolocalización IPv4 tras una transferencia
ipv4networkingtransfer

Corregir la geolocalización IPv4 tras una transferencia

¿Su bloque IPv4 transferido sigue mostrando el país anterior? Verifique WHOIS, BGP y GeoIP, publique un geofeed y solicite correcciones a cada proveedor.