
Consulenza e analisi per CVE-2026-111497, una scrittura fuori dai limiti nel decoder Brotli raggiungibile tramite la decompressione HTTP di Node.js, con causa principale, diff della patch, regole di rilevamento e mitigazioni.
Ultimo controllo: 2026-11-04 (KST). Ogni valore è stato riportato solo se verificato nelle fonti indicate in References; in caso di discrepanze tra le fonti, sono stati indicati tutti i valori.
c/dec/decode.c) ignora il valore di errore restituito da un cambio di blocco non valido, continuando la decodifica in uno stato corrotto ed eseguendo una scrittura fuori dai limiti del buffer (Out-of-Bounds Write).Brotli/brotlicffi, Bun, .NET, Envoy, Istio, ecc. È necessario che esista un percorso di decompressione di dati Content-Encoding: br controllati dall'attaccante.| Voce | Contenuto |
|---|---|
| CVE ID | CVE-2026-111497 (GHSA-9v8h-qqgm-4m35) |
| Alias | Node2Shell (denominazione Imperva), HTTP2Shell, Broccoli2Shell. Nonostante il nome, non è un difetto del protocollo HTTP/2 |
| Data di pubblicazione | 21-10-2026 rilascio di sicurezza Node.js e patch Brotli / 22-10-2026 pubblicazione record CVE |
| Scopritori | OpenAI Codex Security (Khai Tran, Sylvie Mayer) |
| Prodotti/versioni interessate | Google Brotli (libbrotlidec) 1.0.3 ~ 1.2.0 e prodotti che lo includono o collegano (vedi tabella sotto) |
| Versioni patchate | Brotli 1.0.10 / 1.1.1 / 1.2.1, Node.js 22.23.4 / 24.22.1 / 26.12.1, Python Brotli 1.2.1, brotlicffi 1.2.1.0, Bun 1.4.4 |
| CVSS v4.0 (CNA: Google) | 9.2 Critico — CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| CVSS v3.1 (NVD) | 9.8 Critico — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CVSS v3.1 (Red Hat / Amazon Linux) | 8.1 — CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (riflette i requisiti di attacco AT:P e l'hardening della piattaforma) |
| Valutazione del vendor | Node.js: Alto / Red Hat: Importante |
| CWE | CWE-787 Scrittura fuori dai limiti (NVD, Red Hat, Canadian Cyber Centre) / CWE-252 Valore di ritorno non controllato (descrizione CISA KEV, indicata come causa principale in alcune analisi) |
| Sfruttamento attivo | Confermato. Inserimento in CISA KEV il 27-10-2026, termine per le agenzie federali 10-11-2026. Operatori di honeypot (Previdian, ELLIO) hanno osservato tentativi di sfruttamento il 26-27/10 |
| Componente | Versioni interessate | Versioni corrette |
|---|---|---|
| Google Brotli (C, libbrotlidec) | 1.0.3 ~ 1.2.0 | 1.0.10, 1.1.1, 1.2.1 |
| Node.js 26.x (Current) | precedenti alla 26.12.1 | 26.12.1 |
| Node.js 24.x (LTS) | precedenti alla 24.22.1 | 24.22.1 |
| Node.js 22.x (LTS) | precedenti alla 22.23.4 | 22.23.4 |
| Node.js 25.x / 23.x / 20.x e inferiori | tutte le versioni (EOL) | nessuna patch → migrare a 22/24/26 |
| Bun | 1.4.3 e inferiori | 1.4.4 |
Python Brotli (PyPI) | 1.2.0 e inferiori | 1.2.1 |
Python brotlicffi | precedenti alla 1.2.1.0 | 1.2.1.0 |
| .NET / PowerShell | vedi avviso del vendor | Aggiornamento urgente .NET Microsoft (dotnet/announcements#494) |
| Envoy / Istio | vedi avviso del vendor | Rilascio correttivo distribuito a inizio ottobre (senza menzione esplicita del difetto) |
| VMware SDDC Manager (VCF / vSphere Foundation) | vedi avviso Broadcom | vedi avviso Broadcom |
Percorsi di esposizione indiretta: Python requests, urllib3, aiohttp[speedups], httpx decompressione automaticamente le risposte br se Brotli/brotlicffi è installato. Anche curl è interessato quando si utilizza l'opzione di decompressione.
| Data | Evento |
|---|---|
| 02-27 | Commit di correzione applicato al repository google/brotli (contrassegnato come problema di sicurezza, non rilasciato) |
| Inizio ottobre | Rilascio delle versioni corrette di Envoy / Istio |
| 10-21 | Rilascio di sicurezza di Node.js (22.23.4 / 24.22.1 / 26.12.1), rilascio di Google Brotli 1.0.10 / 1.1.1 / 1.2.1 |
| 10-22 | Pubblicazione del record CVE, Imperva dimostra l'esecuzione di codice su Node.js 24.22.0 (Linux arm64) |
| 10-23 | Distribuzione dei pacchetti PyPI corretti |
| 10-25 | Avviso e aggiornamento di Microsoft .NET |
| 10-26 | ELLIO segnala traffico di sfruttamento |
| 10-27 | Inserimento in CISA KEV (scadenza per l'intervento 11-10) |
⚠️ Alcuni articoli di analisi scritti tra il 24 e il 28 ottobre riportano "nessun attacco reale confermato, non inserito in KEV", ma ciò si riferisce al periodo precedente all'inserimento in KEV e quindi è diverso dalla situazione attuale.
BROTLI_FALSELa decodifica Brotli è una macchina a stati (state machine). Il flusso è composto da unità chiamate metablocchi (metablock) e, all'interno di ciascun metablocco, compaiono istruzioni che eseguono un cambio di blocco (block switch) del tipo di blocco per letterali (literal), comandi di inserimento-copia (insert-and-copy command) e distanze (distance).
DecodeBlockTypeAndLength() interpreta il cambio di blocco e restituisce un BROTLI_BOOL. Il problema è che BROTLI_FALSE è stato usato con due significati completamente diversi.
| Significato | Natura | Gestione corretta |
|---|---|---|
| È necessario più input (needs more input) | Recuperabile | Attendere l'input successivo e riprendere |
| Il metablocco contiene un solo tipo di blocco, quindi il cambio stesso è impossibile | Errore di formato fatale | Rifiutare lo stream |
Il chiamante non ha verificato questo valore di ritorno.
DecodeCommandBlockSwitch) è dichiarato come static void e non conserva il valore di ritorno, e anche il ramo non-safe della macro BROTLI_SAFE si limita a chiamare la funzione e scarta il risultato. (Analisi di SonicWall)DecodeLiteralBlockSwitch) il valore di ritorno viene completamente scartato. Sebbene le funzioni indicate differiscano tra le analisi, secondo la descrizione della patch della distribuzione (TuxCare) tutti e tre i decoder di cambio blocco — literal, comando e distanza — sono stati modificati per restituire un codice di errore, quindi si può ritenere che tutti e tre i percorsi siano coinvolti.Di conseguenza, anche se si verifica un errore di formato, il decoder continua come se il cambio fosse riuscito, il contatore della lunghezza del blocco rimane a 0 e lo stato di posizione (position) e distanza viene trasferito in un percorso che avrebbe dovuto essere rifiutato.