Brotli CVE-2026-111497: aggiornare Node.js, Bun e Python

Brotli CVE-2026-111497: aggiornare Node.js, Bun e Python

Brotli CVE-2026-111497: aggiornare Node.js, Bun e Python

CVE-2026-111497 è un bug di corruzione della memoria nel decoder Brotli di Google, il codice C che decomprime i dati Content-Encoding: br. Dati compressi costruiti ad arte scrivono oltre la fine di un buffer, e questo può mandare in crash il programma, far trapelare memoria o eseguire il codice dell'attaccante. Node.js, Bun, i pacchetti Python Brotli e brotlicffi ed Envoy includono ciascuno la propria copia del decoder, quindi ognuno va aggiornato separatamente. Questa guida mostra quando un'applicazione è davvero esposta, come controllare un server con un solo comando e come distribuire la correzione senza dimenticare alcun container.

Quanto è grave

  • Google le assegna 9.2 (critical) su CVSS 4.0, Node.js la classifica high, Red Hat 8.1.
  • I ricercatori di Imperva hanno eseguito il proprio codice su un Node.js 24.22.0 non aggiornato su Linux ARM64, sia tramite una risposta ottenuta con fetch sia tramite il corpo di una richiesta Express. L'exploit non è pubblico.
  • La valutazione della CISA del 23 ottobre non ha registrato sfruttamenti reali, e non esiste un proof of concept pubblico affidabile.
  • La falla funziona in entrambe le direzioni: un server che decomprime input compressi può essere attaccato da un client, e un client che decomprime risposte compresse può essere attaccato da un server.

La correzione è entrata nel codice sorgente di Brotli il 27 febbraio, ma nessuna release di Brotli l'ha inclusa fino al 21 ottobre: per questo tutti i runtime corretti sono usciti nella stessa settimana.

Sei esposto?

È a rischio solo il codice che decodifica dati Brotli controllati da qualcun altro:

  • Node.js e Bun - il fetch() integrato quando legge una risposta inviata con Content-Encoding: br, le chiamate Brotli di node:zlib su dati non attendibili e i parser del corpo che decomprimono upload in Brotli (Express 5, body-parser 2). Un semplice server HTTP Node.js non decodifica da solo il corpo delle richieste.
  • Python - basta che sia installato il pacchetto Brotli o brotlicffi: requests, urllib3, httpx e aiohttp decodificano allora da soli le risposte Brotli, anche se il tuo codice non importa mai Brotli.
  • Envoy e Istio - solo se è configurato un filtro di decompressione Brotli.

Qualsiasi servizio che chiama API di terze parti, webhook, provider di pagamento o fa scraping di pagine esegue fetch() verso server che non controlli. Togliere br da Accept-Encoding non è una correzione: un server può inviare Brotli comunque.

Software Vulnerabile Corretto in
Node.js 22.x, 24.x, 26.x prima della correzione; 20.x e precedenti (fine supporto) 22.23.4, 24.22.1, 26.12.1
Bun 1.4.3 e precedenti 1.4.4
Python Brotli 1.2.0 e precedenti 1.2.1
Python brotlicffi 1.2.0.x e precedenti 1.2.1.0
Google Brotli (libreria 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

Controllare un server con un comando

Questo script shell POSIX esamina Bun, Node.js e Python sulla macchina (o dentro un container) e indica quali sono più vecchi della correzione. Salvalo come 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

Output verificato il 2026-10-24 (un portatile di sviluppo, poi le immagini Docker ufficiali):

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

Eseguilo in ogni container, non solo sull'host: il Node.js dell'host non dice nulla di quello incluso in un'immagine.

Come distribuire la correzione

  1. Trova ogni copia. Le immagini sono la dimenticanza più comune. Elenca cosa è in esecuzione: docker ps --format '{{.Image}}', poi le righe FROM dei tuoi Dockerfile. Un tag come node:22 o oven/bun:alpine avanza solo quando fai pull; un tag fissato come oven/bun:1.4.1-slim non avanza mai.
  2. Aggiorna il runtime. Alza i tag fissati (oven/bun:1.4.4-slim, node:22.23.4-alpine), esegui bun upgrade e aggiorna i pacchetti Node.js sugli host, e pip install -U "Brotli>=1.2.1" (o brotlicffi>=1.2.1.0) negli ambienti Python. Se un'applicazione Python non ha bisogno di Brotli, anche pip uninstall Brotli brotlicffi chiude la strada: i client HTTP ripiegano su gzip e deflate.
  3. Ricostruisci e sostituisci. docker compose build --pull && docker compose up -d. Un processo in esecuzione mantiene il vecchio decoder finché non viene riavviato, quindi riavvia anche i servizi sugli host.
  4. Verifica. Esegui di nuovo lo script di controllo in ogni container (docker exec <name> bun --version è la versione rapida). I lockfile con --frozen-lockfile possono far fallire la ricostruzione dopo l'aggiornamento delle dipendenze: fai commit del lockfile aggiornato insieme a package.json.
  5. Non puoi ancora aggiornare? Rifiuta sul proxy le richieste con Content-Encoding: br prima che qualcosa decodifichi il corpo, ed evita di scaricare dati da host non attendibili. Vercel fa notare che le regole del firewall non coprono le risposte che il tuo stesso codice scarica da altri server - lì serve solo l'aggiornamento.

Per uno stack Node.js su una VM vedi Server cloud per Node.js, per Python Server cloud per Python e Flask e per immagini che si ricostruiscono senza intoppi Server cloud per Docker Swarm.

Cosa abbiamo fatto

Nel giro di pochi giorni dalle correzioni abbiamo portato a 1.4.4 ogni servizio DCXV che gira su Bun: le immagini base fissate sono passate a tag corretti e tutte le immagini sono state ricostruite con un pull nuovo. I nostri componenti Node.js non decodificano corpi Brotli e i nostri proxy non hanno decompressione Brotli. I server dei clienti sono gestiti dai loro proprietari: se usi Node.js, Bun o Python su un server cloud DCXV, esegui oggi stesso il controllo qui sopra, oppure chiedici dell'amministrazione gestita dei server.

Fonti (verificate il 2026-10-24): le release di sicurezza di Node.js di ottobre 2026 (22.23.4, 24.22.1, 26.12.1), la release Bun 1.4.4, la valutazione della CISA del 23 ottobre 2026 e la ricerca di Imperva.

PHP2Shell: come verificare e correggere le falle RCE di PHP
clouddedicatedhosting

PHP2Shell: come verificare e correggere le falle RCE di PHP

PHP2Shell (CVE-2026-109618, CVE-2026-109619) fa sì che una richiesta non autenticata esegua codice in PHP. Versioni corrette, script testato, rimedi in php.ini e piano.

Brotli CVE-2026-111497: aggiornare Node.js, Bun e Python
cloudnetworkinginfrastructure

Brotli CVE-2026-111497: aggiornare Node.js, Bun e Python

Una falla del decoder Brotli (CVE-2026-111497) può eseguire codice via fetch() in Node.js e Bun o nei client HTTP Python. Versioni corrette, script di verifica e ricostruzione.

Server cloud per SaaS: dimensionare CPU, RAM, NVMe e backup
cloudinfrastructurepricing

Server cloud per SaaS: dimensionare CPU, RAM, NVMe e backup

Dimensiona un server cloud per SaaS con Docker e Node.js: memoria, limiti CPU, NVMe e backup, test di carico k6, prezzo mensile completo e una scheda più pratica.

Agenti di codice IA su VPS UE: configurazione rinforzata
aicloudhosting

Agenti di codice IA su VPS UE: configurazione rinforzata

Ospita agenti di codice IA su un VPS UE con limiti: workspace usa e getta, uscita consentita, token limitati, codice testato, rischi e costi, più un esempio.

Correggere la geolocalizzazione IPv4 dopo un trasferimento
ipv4networkingtransfer

Correggere la geolocalizzazione IPv4 dopo un trasferimento

Il blocco IPv4 trasferito mostra ancora il paese precedente? Verificate WHOIS, BGP e GeoIP, pubblicate un geofeed e chiedete correzioni più mirate ai fornitori.