Google Brotli CVE-2026-111497 (Node2Shell): un flusso compresso porta all'esecuzione di codice senza credenziali, sfruttata e in KEV
La CVE-2026-111497 è una scrittura fuori dai limiti della memoria (CWE-787) nel decoder di Google Brotli, la libreria open source di compressione usata per i contenuti web e incorporata in Node.js, .NET, nelle librerie Python e in molti altri prodotti. In rete circola con tre nomi, Node2Shell, Broccoli2Shell e HTTP2Shell. Google, che ha assegnato la CVE, le dà un CVSS 4.0 di 9.2, critico; Node.js, che l'ha divulgata, la classifica di gravità alta. Il meccanismo, nella descrizione di Node.js: un cambio di blocco non valido veniva trattato come una temporanea richiesta di altri dati invece che come un errore di formato, e il decoder continuava ad accodare byte in un buffer interno di otto. Chi riesce a far decomprimere a un'applicazione un flusso Brotli predisposto, senza bisogno di credenziali, può mandare in crash il processo, leggerne la memoria e in alcuni casi eseguire codice. Lo sfruttamento attivo è confermato: il 27 ottobre la CISA ha inserito la CVE nel catalogo KEV, con termine di remediation fissato al 10 novembre, e il 28 ottobre ACN ha aggiornato il proprio alert per lo sfruttamento rilevato in rete.
Il difetto è nel codice dalla versione 1.0.3 di Brotli, del marzo 2018. Come ricostruiscono ELLIO e Help Net Security, la correzione era stata scritta il 27 febbraio 2026 ed era finita nel ramo pubblico del progetto senza una release né un advisory, restando leggibile per otto mesi. È diventata un caso il 21 ottobre, quando Node.js l'ha divulgata insieme agli aggiornamenti dei rami 22, 24 e 26; l'advisory accredita la scoperta a Khai Tran e Sylvie Mayer di OpenAI Codex Security. Le versioni correttive di Brotli, la 1.0.10, la 1.1.1 e la 1.2.1, e la scheda della CVE sono arrivate nei giorni successivi. ACN aveva segnalato la falla il 21 ottobre nell'alert sugli aggiornamenti di Node.js e il 26 ottobre le ha dedicato un alert specifico, per la prova di concetto disponibile. Quella pubblicata il 22 ottobre, secondo Datadog Security Labs, sulle build standard produce un crash e una lettura limitata della memoria. Il quadro è cambiato in pochi giorni: ELLIO ha ottenuto una shell su x86-64 contro quattro bersagli con i binari ufficiali e la configurazione predefinita (un server HTTP di Node.js senza framework, l'immagine container ufficiale della 24.22.0 eseguita come root, Express 5.3.0 e Koa 3), e il 26 ottobre i suoi sensori hanno registrato traffico d'attacco che usava l'exploit pubblico, preceduto il giorno prima da uno strumento che verificava quali host decomprimono Brotli. Per ELLIO l'indirizzo da cui partivano gli attacchi era già noto per lo sfruttamento di PHP2Shell, di cui abbiamo scritto in un nostro precedente alert del 25 ottobre sulle CVE-2026-109618 e 109619 di PHP2Shell, e per le scansioni delle VPN Palo Alto GlobalProtect e FortiOS: un operatore che lavora sullo sfruttamento di massa.
Partita come un problema di Node.js, la falla riguarda chiunque incorpori il decoder. Datadog Security Labs ha messo in fila i prodotti con un advisory proprio: le librerie Python Brotli e brotlicffi fino alla 1.2.0, Bun dalla 1.0.21 alla 1.4.3, la libreria Java brotli4j fino alla 1.23.0, .NET 8, 9 e 10 prima dell'aggiornamento straordinario del 25 ottobre, i proxy Envoy e Istio. Due dettagli contano: brotli4j porta dentro i propri jar una copia nativa di Brotli, che l'aggiornamento della libreria di sistema non tocca, e gli eseguibili compilati con Bun restano vulnerabili finché non si ricompilano. Si è esposti quando un'applicazione decomprime dati Brotli controllati da un attaccante, e le strade sono due. In ingresso, Express 5 e body-parser 2.x accettano per impostazione predefinita corpi di richiesta compressi con Brotli, e Koa e NestJS ereditano il comportamento; se il parser è montato prima dell'autenticazione, il decoder è raggiungibile da chiunque. In uscita la strada è meno visibile: la funzione fetch() di Node.js decomprime da sola le risposte marcate Brotli, anche quando l'applicazione non le ha chieste, quindi webhook, anteprime di link e lettori di feed che scaricano URL indicati dagli utenti lasciano all'attaccante la scelta della risposta. Datadog avverte che, siccome la decompressione avviene dentro l'applicazione, né il server web né un WAF vedono il contenuto malevolo, e che sulla 24.22.1 corretta l'indicazione interna della versione di Brotli riporta ancora 1.2.0: per la verifica fa fede la versione di Node.js.
Chi se ne deve preoccupare: chi espone servizi scritti in Node.js, dalle API ai backend dei portali, e chi usa applicazioni .NET, client e servizi Python con Brotli installato, Bun, Java con brotli4j, Envoy o Istio. Non risultano dati sulle vittime né sull'esposizione in Italia, ma Node.js è un runtime molto diffuso anche nelle applicazioni web della PA e dei fornitori. Il punto debole sono le immagini container costruite prima del 21 ottobre e i Dockerfile che fissano una versione precisa: continuano a distribuire la build vulnerabile finché qualcuno non cambia quella riga. I rami di Node.js fuori supporto, 20, 23 e 25, contengono lo stesso decoder e non riceveranno correzioni.
- Versioni affette: Google Brotli dalla 1.0.3 alla 1.0.9, 1.1.0 e 1.2.0 (corrette 1.0.10, 1.1.1 e 1.2.1); Node.js 22.x precedenti alla 22.23.4, 24.x precedenti alla 24.22.1, 26.x precedenti alla 26.12.1, più i rami fuori supporto 20.x, 23.x e 25.x, senza correzione; fra i prodotti derivati, Python Brotli e brotlicffi fino alla 1.2.0, Bun dalla 1.0.21 alla 1.4.3, brotli4j fino alla 1.23.0, .NET 8, 9 e 10 precedenti alle 8.0.33, 9.0.22 e 10.0.14, Envoy e Istio nelle release precedenti alla prima correzione di ciascun ramo.
- Azione raccomandata: aggiornare Node.js alla 22.23.4, 24.22.1 o 26.12.1 e migrare dai rami fuori supporto; aggiornare librerie, runtime e pacchetti di distribuzione che incorporano Brotli seguendo gli advisory dei rispettivi produttori, compresi brotli4j, che va aggiornato a parte, e .NET; ricostruire e ridistribuire immagini container ed eseguibili compilati, riavviare i servizi e verificare che i carichi in esecuzione usino davvero i componenti corretti; per le amministrazioni federali statunitensi il termine KEV è il 10 novembre. In attesa dell'aggiornamento, rifiutare sul reverse proxy le richieste con Content-Encoding br e disattivare la decompressione nei parser di Express 5 e body-parser 2.x (opzione inflate impostata a false), sapendo che sono solo mitigazioni: non coprono le risposte decompresse in uscita e possono interrompere funzionalità legittime.
Fonti: ACN, Node.js, CISA, ELLIO, Datadog Security Labs, Help Net Security