26 ottobre 2026 7 min di lettura

CVE-2026-111497: falla nel decoder Brotli riguarda Node.js, Bun, Python, .NET ed Envoy: cosa aggiornare ora

Un errore nel decoder Brotli di Google (versioni da 1.0.3 a 1.2.0) consente, tramite dati appositamente predisposti, una scrittura out-of-bounds fino all'esecuzione di codice (CVE-2026-111497, CVSS 9.2). È interessato qualsiasi software che decomprime dati Brotli provenienti da fonti esterne: Node.js, Bun, Python con Brotli/brotlicffi, .NET, Envoy, curl. Sono disponibili aggiornamenti.

Il decoder Brotli di Google contiene, nelle versioni da 1.0.3 a 1.2.0, un errore che consente a dati Brotli appositamente predisposti di sovrascrivere memoria al di fuori di un buffer. La vulnerabilità ha l’identificativo CVE-2026-111497 e una valutazione di 9.2 secondo CVSS 4.0; pubblicamente è nota con i nomi Node2Shell e Broccoli2Shell. Le possibili conseguenze sono un arresto anomalo, la lettura della memoria del processo o l’esecuzione di codice. Imperva ha dimostrato l’esecuzione di codice su un Node.js 24.22.0 non modificato. Il codice proof-of-concept è in parte pubblico, ma finora non sono noti attacchi in corso. Node.js ha pubblicato le correzioni il 21 ottobre 2026, mentre gli altri ecosistemi hanno seguito entro il 26 ottobre.

Dopo la segnalazione ho verificato i miei sistemi: il build runner di questo sito utilizzava ancora Node.js 22.23.1, nonostante la versione 22.23.4 fosse disponibile da giorni. Il motivo è illustrato nella sezione dedicata a GitHub Actions più avanti; riguarda ogni runner self-hosted con actions/setup-node.

Supporto per inventario e aggiornamenti

Se avete bisogno di aiuto per individuare componenti interessati in applicazioni, immagini container o pipeline CI, utilizzate il modulo di contatto su adeptio.ch. Rispondo anche con breve preavviso.

Causa

L’errore si trova nella funzione DecodeBlockTypeAndLength(). Elabora i cambi di blocco nel flusso di dati compresso, ovvero i punti in cui il decoder passa a un altro codice Huffman. Nelle versioni vulnerabili, la funzione restituisce solo un valore booleano; BROTLI_FALSE significa sia “flusso di dati non valido” sia “necessario altro input”. Un flusso di dati predisposto dichiara un unico tipo di blocco ed esaurisce la sua lunghezza, forzando così un cambio che non può riuscire. Il decoder lo interpreta come input mancante, aggiunge altri byte a un buffer interno di 8 byte e scrive oltre il suo limite.

La correzione upstream (commit 0ed4268 nel repository google/brotli) introduce un proprio codice di errore BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH e interrompe la decodifica. OpenAI Codex Security aveva già segnalato l’errore nel febbraio 2026. All’epoca la correzione era finita nel codice sorgente, ma non era stata classificata come correzione di sicurezza e non è apparsa in alcuna release. È stata distribuita solo con Brotli 1.2.1 e le release Node.js del 21 ottobre 2026.

Quando un sistema è attaccabile

Comprimere con Brotli è innocuo; è attaccabile solo chi decomprime dati Brotli provenienti da una fonte esterna. Ci sono due direzioni:

  • Client: L’applicazione richiama un URL e decodifica una risposta con Content-Encoding: br. Il fetch() integrato di Node.js e Bun lo fa automaticamente e non può essere disattivato. Sono quindi interessati crawler, ricevitori di webhook con callback, anteprime di link, script di monitoraggio e qualsiasi automazione che carichi contenuti da server di terzi. A tale scopo, a un attaccante basta controllare uno dei server richiamati.
  • Server: Un framework o un middleware decomprime request body con Content-Encoding: br. Imperva cita per Node.js body-parser 2.0.0 fino a 2.3.0 ed Express 5.0.0 fino a 5.3.0 con parser configurati json() o raw(). Un server http nativo di Node.js non decodifica autonomamente i body in ingresso.

Apache mod_brotli e i diffusi moduli Brotli per nginx comprimono soltanto e pertanto non sono interessati. Envoy e Istio sono vulnerabili solo se è configurato il filtro Brotli Decompressor; Istio non lo attiva per impostazione predefinita.

Componenti interessati e versioni corrette

ComponenteVersioni corretteNota
libbrotli (Google Brotli)1.2.1, 1.1.1, 1.0.10sono interessate le versioni da 1.0.3 a 1.2.0
Node.js26.12.1, 24.22.1, 22.23.4Release del 21.10.2026, contiene ulteriori correzioni (DNS, verifica del nome TLS)
Bun1.4.4ricompilare gli eseguibili creati con bun build --compile
Python Brotli1.2.1utilizzato automaticamente da urllib3, requests e aiohttp se installato
Python brotlicffi1.2.1.0ugualmente; anche come extra httpx[brotli]
.NET8.0.33, 9.0.22, 10.0.14, 11 RC3aggiornamento out-of-band del 25.10.2026; .NET Framework non interessato, .NET 7 senza correzione
Envoy1.40.0, 1.39.3, 1.38.6, 1.37.8solo con filtro Brotli Decompressor
Istio1.31.2, 1.30.6, 1.29.9solo con Brotli Decompressor in un EnvoyFilter
Java brotli4j1.24.0il wrapper JNI include una propria copia di Brotli
curl/libcurlbuild con Brotli 1.2.1solo con --compressed o CURLOPT_ACCEPT_ENCODING

Ulteriori binding per PHP, Ruby e Go (cgo) dipendono dalla libbrotli di sistema o inclusa nel pacchetto. Tra le distribuzioni Linux, Debian 12 e 13, Alpine e Amazon Linux 2023 avevano pacchetti corretti al 26 ottobre; Fedora e Red Hat erano corretti solo in parte, mentre per Ubuntu e SUSE la correzione era ancora in attesa.

Individuare le versioni interessate

Per Node.js, Python e la libreria di sistema sono sufficienti tre interrogazioni. Su Windows, node -v restituisce lo stesso risultato che su Linux.

node -v
pip show Brotli brotlicffi
pipdeptree -r -p Brotli
Opzioni spiegate
OpzioneEffetto
node -vmostra la versione dell’installazione Node.js attiva
pip show Brotli brotlicffimostra la versione e le dipendenze inverse dei due pacchetti Python, se installati
pipdeptreeelenca l’albero delle dipendenze dei pacchetti Python installati (da installare separatamente)
-rinverte l’albero: mostra quali pacchetti includono il pacchetto indicato
-p Brotlilimita l’output al pacchetto Brotli

Su Debian/Ubuntu e Alpine, il gestore dei pacchetti mostra la versione della libreria di sistema:

dpkg -l 'libbrotli*'
apk info -v brotli-libs
Opzioni spiegate
OpzioneEffetto
dpkg -l 'libbrotli*'elenca tutti i pacchetti installati il cui nome inizia con libbrotli, con la versione
apk info -v brotli-libsmostra il pacchetto Alpine brotli-libs con il numero di versione

Le immagini container devono essere verificate separatamente: un host aggiornato non serve a nulla se l’immagine contiene una vecchia versione di Node.js o una libbrotli inclusa nel pacchetto. Dopo l’aggiornamento, le immagini devono essere ricompilate e i workload in esecuzione riavviati; per Bun e brotli4j questo vale anche per le applicazioni che integrano Brotli staticamente.

Runner GitHub self-hosted: setup-node prende la versione dalla cache

actions/setup-node con node-version: 22 non verifica per impostazione predefinita se esiste una versione 22 più recente. Se nella cache degli strumenti del runner è già presente una versione adatta, viene usata quella. Sui runner ospitati da GitHub, l’immagine viene distribuita nuovamente con regolarità; un runner self-hosted, invece, conserva la cache finché qualcuno non la svuota. Nel log compare quindi, ad esempio, Found in cache @ .../_tool/node/22.23.1/x64.

Una riga aggiuntiva in ogni passaggio setup-node risolve il problema:

- uses: actions/setup-node@v4
  with:
    node-version: 22
    check-latest: true
Opzioni spiegate
OpzioneEffetto
node-version: 22seleziona la versione più recente disponibile della linea 22.x
check-latest: truea ogni esecuzione interroga la directory delle versioni di Node.js e scarica una versione più recente, anziché usare la versione dalla cache degli strumenti

In alternativa, si può indicare in modo fisso la versione minima (node-version: 22.23.4); occorre però aggiornarla a ogni release di sicurezza. Questo è particolarmente rilevante per pipeline che richiamano contenuti da server esterni, come scanner, verificatori di link o feed: in questi casi fetch() comunica con server che non controllate e il runner di norma ha accesso ai secret di deployment.

Se non è subito possibile aggiornare

Le mitigazioni intervengono sulla decodifica:

  • In ingresso: rifiutare al reverse proxy o nel middleware le richieste con Content-Encoding contenente br. Il confronto deve ignorare maiuscole e minuscole e rilevare anche elenchi come gzip, br.
  • In uscita: rimuovere br da Accept-Encoding e scartare le risposte con Content-Encoding: br prima della decodifica. La sola rimozione da Accept-Encoding non è sufficiente, perché un server predisposto può comunque inviare la codifica. Con il fetch() integrato di Node.js e Bun non è possibile; in quel caso aiuta solo l’aggiornamento.
  • curl: omettere --compressed; in libcurl mantenere CURLOPT_ACCEPT_ENCODING su NULL.
  • Python: disinstallare Brotli e brotlicffi, quindi rimuovere dalle dipendenze extra come httpx[brotli]. urllib3, requests e aiohttp ricadranno quindi su gzip e deflate.
  • Envoy/Istio: rimuovere il Brotli Decompressor dalla configurazione o dagli EnvoyFilter e controllare la configurazione in esecuzione.

Cloudflare Workers e browser

Chi esegue applicazioni come Cloudflare Worker non gestisce un proprio processo Node.js; la runtime workerd è gestita e aggiornata da Cloudflare. Al 26 ottobre non era disponibile una dichiarazione di Cloudflare su CVE-2026-111497 e i clienti non possono modificare nulla nella runtime stessa. Restano però interessati gli strumenti attorno al Worker: script di build, wrangler e ambienti di sviluppo locali vengono eseguiti su Node.js e dovrebbero usare una versione corretta. I browser usano implementazioni Brotli proprie; nelle comunicazioni dei produttori e dei ricercatori di sicurezza non sono indicati come interessati.

Cronologia

DataEvento
Febbraio 2026OpenAI Codex Security segnala l’errore; la correzione finisce nel codice sorgente di Brotli senza release
21.10.2026Node.js pubblica 26.12.1, 24.22.1 e 22.23.4
22.10.2026Brotli 1.2.1 e brotlicffi 1.2.1.0 su PyPI; analisi di Imperva con esecuzione di codice
23.10.2026Correzioni per libbrotli, Bun, Envoy e Istio
24.10.2026brotli4j 1.24.0, pacchetti per Amazon Linux 2023
25.10.2026Aggiornamenti out-of-band per .NET
26.10.2026Debian e Alpine corretti, Fedora e Red Hat parzialmente

Fonti

  1. Node.js: October 2026 Security Releases

    advisory ufficiale con causa, linee interessate e versioni corrette, nonché altre nove CVE della stessa release.

    https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
  2. NVD: CVE-2026-111497

    voce CVE con valutazione CVSS 4.0 di 9.2.

    https://nvd.nist.gov/vuln/detail/cve-2026-111497
  3. Imperva: Node2Shell, from Brotli data to remote code execution

    analisi tecnica con dimostrazione dell’esecuzione di codice, percorsi client e server in Node.js, versioni interessate di Express e body-parser.

    https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
  4. Aikido: Python packages vulnerable to Node2Shell

    causa in DecodeBlockTypeAndLength(), versioni corrette per tutti gli ecosistemi, cronologia e mitigazioni; aggiornato continuamente.

    https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497
  5. Microsoft .NET Blog: .NET October 2026 out-of-band security updates
  6. Broccoli2Shell

    pagina informativa sulla vulnerabilità con il suo secondo nome.

    https://broccoli2shell.com/
  7. heise online: Vulnerabilità nel decoder Brotli non solo in Node.js, ma anche in Bun, Python e altro
  8. actions/setup-node: check-latest

    documentazione dell’opzione che a ogni esecuzione verifica la cache degli strumenti rispetto alla directory delle versioni.

    https://github.com/actions/setup-node#check-latest-version

Commenti

I commenti vengono caricati da GitHub / Giscus.