Vai al contenuto principale

#nodejs

Node2Shell (CVE-2026-111497): la RCE nel decoder Brotli di Node.js e Bun, e come proteggersi

Quando un decoder diventa un vettore di attaccoLa compressione Brotli è ormai lo standard de facto per ridurre il peso delle risposte HTTP e, sempre p

Altro...

Quando un decoder diventa un vettore di attaccoLa compressione Brotli è ormai lo standard de facto per ridurre il peso delle risposte HTTP e, sempre più spesso, anche dei body delle richieste in ingresso. È implementata nativamente dentro Node.js, e in una quantità di middleware che la maggior parte degli sviluppatori utilizza senza nemmeno saperlo: body-parser, i parser di Koa, @fastify/compress, e persino il fetch() globale. Quando un bug critico colpisce proprio questo strato, l’impatto non si limita a un singolo pacchetto : si propaga a runtime diversi, framework diversi e migliaia di applicazioni che non hanno mai scelto consapevolmente di usare quel codice.

È esattamente quello che è successo con Node2Shell, la vulnerabilità identificata come -2026-111497, resa pubblica il 22 ottobre 2026 insieme alle versioni corrette di Node.js e Bun. Vale la pena capire bene il meccanismo, perché non si tratta di un bug “di libreria terza parte”, ma di un difetto nel cuore stesso del runtime.

Il meccanismo tecnico: un out-of-bounds write nel decoder BrotliNode2Shell è classificata come CWE-787 (Out-of-bounds Write) e CWE-252, e risiede nella libreria C google/brotli che Node.js e Bun impacchettano al loro interno — non nel pacchetto npm brotli, che non è coinvolto. Il formato dello stream Brotli prevede la dichiarazione di “block type” multipli all’interno del flusso compresso. Il bug nasce quando uno stream dichiara un solo block type e poi, più avanti nello stream, tenta comunque di switchare verso un altro blocco: il decoder non rifiuta questa transizione illegale e continua a decodificare in uno stato interno non valido, finendo per scrivere oltre i limiti del buffer allocato.

Il fix è stato effettivamente committato nel repository google/brotli il 27 febbraio 2026, ma senza alcuna o advisory pubblica collegata — il che significa che per quasi otto mesi la correzione è rimasta “silenziosa” finché i ricercatori di sicurezza Codex (Khai Tran e Sylvie Mayer) non l’hanno segnalata formalmente al team Node.js, innescando il processo di CVE e il rilascio coordinato delle .

Versioni affette e versioni corretteComponenteVersioni affetteVersione con fixNode.js 26.x< 26.12.126.12.1Node.js 24.x< 24.22.124.22.1Node.js 22.x< 22.23.422.23.4Node.js 20.x e linee EOLtutte le release che impacchettano Brotlinessuna patch — va fatto l’upgrade a una linea supportataBun< 1.4.41.4.4libreria Brotli1.0.3–1.0.9, 1.1.0, 1.2.01.0.10, 1.1.1, 1.2.1Google, in qualità di CNA, ha assegnato un punteggio CVSS 4.0 pari a 9.2 (Critical); il team Node.js la classifica come “High” e conferma esplicitamente che il difetto può portare a remote code execution. Degno di nota: anche il pacchetto Python Brotli di Google impacchetta lo stesso decoder vulnerabile ed è corretto nella versione 1.2.1, quindi chi gestisce pipeline Python che processano contenuti Brotli non ufficiali dovrebbe verificare anche quel lato.

Dove si trova la superficie di attacco realeIl punto cruciale per chi deve valutare l’esposizione non è “uso Node.js?”, ma “qualcosa nella mia stack decodifica automaticamente Brotli su dati non fidati?”. Le combinazioni più comuni ad alto rischio sono:

Express 5 + body-parser 2.x: i metodi json(), urlencoded(), text() e raw() decodificano automaticamente i body con Content-Encoding: br. Express 4 e body-parser 1.x, invece, non lo fanno — un buon motivo in più per non ritardare la migrazione a Express 5.

Koa, tramite koa-bodyparser, @koa/bodyparser, koa-body o co-body.

Fastify, quando è attivo @fastify/compress con la decompressione delle richieste in ingresso.

Il fetch() integrato in Node.js e Bun, che decodifica automaticamente le risposte Brotli: qualunque servizio che scarica contenuti da URL controllati (anche indirettamente) da un utente è potenzialmente esposto.

Uso diretto di zlib.brotliDecompress, brotliDecompressSync o createBrotliDecompress su dati non fidati.

Un semplice server http nativo, senza middleware di decompressione, non decodifica automaticamente i body Brotli e quindi non è esposto per quella via — un dettaglio utile per dare priorità alla remediation.

Stato dell’exploitationAl 23 ottobre 2026 risultava già dimostrata pubblicamente l’esecuzione di codice sull’immagine Docker ufficiale di Node.js 24.22.0 arm64, con un proof-of-concept pubblicato. Non risultano, al momento, campagne di sfruttamento attivo in the wild, e la CVE non è ancora presente nel catalogo CISA KEV — ma dato che il PoC è pubblico e il bug è banalmente raggiungibile da qualunque endpoint HTTP che accetti body compressi, la finestra di rischio va considerata stretta.

Come individuare l’esposizione nella propria infrastrutturaPrima di tutto, va fatto un inventario mirato invece di un generico “controllare la versione di Node”:

Cercare nei Dockerfile le immagini base che puntano a versioni vulnerabili di Node.js o Bun, incluse le linee end-of-life e le immagini pinnate per digest (che vanno riviste manualmente perché il tag non rivela la versione).

Cercare righe nvm install o script NodeSource che installano versioni vulnerabili nelle pipeline di CI/CD.

Dare priorità ai servizi che combinano un runtime vulnerabile con una dipendenza che decodifica Brotli (Express 5, body-parser 2, parser Koa, @fastify/compress).

Ispezionare le immagini container già costruite per individuare runtime vulnerabili o librerie Brotli di sistema nel range affetto — attenzione: alcune distribuzioni Linux applicano backport dei fix mantenendo numeri di versione apparentemente “vecchi”, quindi va controllato l’advisory specifico della distribuzione.

Verificare anche i binari standalone generati con bun build --compile, che incorporano il runtime e vanno ricompilati.

Mitigazione immediata# 1. Verifica rapida della versione installata
node -v
bun --version

2. Aggiornamento Node.js (esempio con nvm)

nvm install 24.22.1
nvm alias default 24.22.1

3. Aggiornamento Bun

bun upgrade --version 1.4.4
Se un upgrade immediato non è possibile, due mitigazioni temporanee (da sostituire appena possibile con la patch vera):

A livello di reverse proxy (esempio nginx), rifiuta Content-Encoding: br

anche quando compare in liste come "gzip, br"

if ($http_content_encoding ~* "br") {
return 415;
}
In alternativa, si può disattivare l’inflate nei body parser applicativi — ma attenzione: questo blocca anche i body compressi in gzip, quindi è un compromesso drastico da usare solo come tampone di emergenza. Nessuna delle due mitigazioni copre il caso di fetch() che decodifica risposte Brotli in arrivo da terzi: per quel vettore l’unica soluzione reale è l’aggiornamento del runtime.

ConclusioneNode2Shell è un promemoria scomodo ma utile: le librerie di decompressione sono codice “di sistema” tanto quanto il kernel o la libc, eppure vengono quasi sempre trattate come dettaglio implementativo invisibile. Un bug qui ha un raggio d’azione che attraversa runtime (Node.js, Bun), linguaggi (Python) e letteralmente ogni framework web che si appoggia a quella decodifica. Per chi gestisce infrastrutture Node.js in produzione, la lezione pratica è duplice: primo, includere esplicitamente la versione del runtime — non solo delle dipendenze npm — nei processi di vulnerability scanning; secondo, trattare le immagini container pinnate per digest come un rischio aggiuntivo, perché “non è cambiato il tag” non significa “non serve ricontrollare”.

Fonte: Cycode – node2shell (CVE-2026-111497): What to Patch and How to Find Exposed Services

#sicurezza #cve #vulnerabilità #dev #bun #rce #nodejs

1

Caricamento...

0
1

Caricamento...

Node.js Patches Brotli RCE and High-Severity TLS and DNS Flaws

Read Time:3 Minute, 26 Second

The Node.js project has released security updates for its supported 26.x, 24.x and 22.x b

Altro...

Read Time:3 Minute, 26 Second

The Node.js project has released security updates for its supported 26.x, 24.x and 22.x branches, addressing ten vulnerabilities across compression, TLS verification, DNS handling, HTTP connections, cryptographic randomness and filesystem permissions. Four issues are rated high severity, with a Brotli decoder memory corruption bug carrying the most serious potential outcome: remote code execution.

The patched releases are Node.js 26.12.1, 24.22.1 and 22.23.4. Operators should install the appropriate version for their branch, rebuild containers and serverless bundles that embed the runtime, and restart long-running services. Merely updating a development workstation will not replace Node.js copies already shipped in production images.

Brotli decoder bug can cross a trust boundaryCVE-2026-111497 is an out-of-bounds write in the Brotli decoder affecting all three supported release lines. Writing beyond an allocated memory region can crash a process and, under suitable conditions, enable attacker-controlled code execution. Applications that automatically decompress untrusted Brotli content should be prioritized because remote input may reach the affected component.

The available advisory information does not fully describe the exploitation requirements. That uncertainty should not be interpreted as evidence of low risk. Internet-facing gateways, content-processing services and applications that accept compressed uploads have a clearer exposure path than systems that never handle attacker-controlled compressed data.

TLS and DNS inconsistencies weaken destination checksTwo high-severity vulnerabilities affect certificate hostname verification. CVE-2026-105483 concerns IP addresses written with full-width digits and affects the 26.x and 24.x branches. CVE-2026-106069 applies when a hostname loosely resolves to an IP address and affects 26.x, 24.x and 22.x. Both can cause an application to accept a certificate that should not match the intended endpoint.

These flaws are especially relevant to services that make outbound HTTPS requests based on user-controlled or tenant-provided destinations. Certificate validation is a core boundary against interception and redirection; unusual hostname representations should not produce a different security decision from their conventional form.

The fourth high-severity issue, CVE-2026-105482, causes dns.resolve to truncate names containing a NUL character. Security checks that inspect one string while the resolver uses a shortened version can create validation gaps. The bug affects all three supported branches.

Other fixes cover HTTP, randomness and permissionsCVE-2026-105481 addresses a keep-alive connection that can process a response written before its corresponding request was sent. CVE-2026-106072 corrects certificate validation for nonstandard IPv4 hostnames. Both are rated medium and apply to the supported branches.

Another medium-severity issue, CVE-2026-106074, can cause processes created from startup snapshots or single executable applications to repeat values returned by crypto.randomUUID() and crypto.randomInt(). Applications must not assume identifiers are unpredictable when runtime state has been cloned incorrectly.

Low-severity fixes address untrusted bytes exposed after failed ZIP header validation, wildcard behavior that grants excess filesystem access, and a Permission Model bypass through fs.realpathSync. The release also refreshes bundled components such as c-ares, CA certificates, Undici, OpenSSL and SQLite, depending on the branch.

What engineering teams should do nowInventory the exact Node.js runtime in hosts, containers, build images and serverless packages.

Upgrade to 26.12.1, 24.22.1 or 22.23.4 and replace immutable artifacts.

Test outbound HTTPS, DNS resolution and Brotli content handling after the update.

Review applications that use startup snapshots or single executables for security-sensitive random values.

Migrate any end-of-life Node.js branch to a supported release line.

Teams should also verify the runtime from inside the deployed artifact rather than trusting a manifest or base-image tag. Moving tags can leave cached layers in place, and package-lock updates do not necessarily upgrade the Node.js executable.

The breadth of this release makes it relevant even to applications that do not use Brotli directly. TLS and DNS behavior sits underneath common HTTP libraries, while embedded runtime copies can be easy to miss. A complete response combines patching with an inventory of where Node.js actually executes across the delivery pipeline.

#remotecodeexecution #nodejs #tlssecurity #brotli

0

Caricamento...

0
0

Caricamento...

npm Trusted Publishing sotto attacco: la falla SlugFest e come GitHub l’ha corretta

Il problema: la fiducia basata su un nome che può cambiare proprietarioA inizio ottobre 2026 ha corretto una falla nel sistema Trusted Pu

Altro...

Il problema: la fiducia basata su un nome che può cambiare proprietarioA inizio ottobre 2026 ha corretto una falla nel sistema Trusted Publishing che, secondo la società di sicurezza Bloom Security, lasciava più di 1.500 pacchetti (oltre 10 milioni di download complessivi) esposti a un takeover senza bisogno di rubare alcuna credenziale. Il bug, battezzato SlugFest, è un ottimo caso di studio per chiunque gestisca pipeline CI/CD: mostra come un meccanismo pensato per eliminare i segreti a lunga durata possa comunque fallire se il vincolo di fiducia è ancorato alla cosa sbagliata.

Trusted Publishing è arrivato su npm a luglio 2025 come alternativa ai token di pubblicazione statici. L’idea è elegante: il provider CI/CD (tipicamente GitHub Actions) genera un token OIDC di breve durata ad ogni esecuzione del workflow; npm lo scambia con una credenziale di pubblicazione temporanea solo se il token corrisponde a una configurazione di “trusted publisher” preregistrata sul pacchetto (repository, workflow, ambiente). Niente più NPM_TOKEN salvato nei secret di GitHub, niente più credenziali che restano valide per mesi se qualcuno le intercetta.

Dove si è rotto il modello: lo slug non è un identificatore stabileIl difetto individuato dal ricercatore Golan Myers di Bloom Security riguarda a cosa è legata la configurazione di trusted publisher. npm vincola il publisher allo slug del repository, cioè alla stringa owner/repository, e non all’ID numerico immutabile che GitHub assegna internamente a ogni repository. Il token OIDC generato da GitHub Actions contiene in realtà anche quell’ID, ma npm lo ignora fino a quando non avviene la prima pubblicazione riuscita da quel repository.

Myers l’ha descritta con un’immagine efficace: è come una serratura che controlla l’indirizzo scritto sulla porta invece di verificare chi sia il legittimo proprietario della casa. Se uno slug si libera — perché il repository viene rinominato, trasferito a un altro account o cancellato — chiunque lo rioccupi su GitHub eredita automaticamente la fiducia che npm aveva associato a quel nome.

La catena d’attacco passo per passoL’attaccante identifica un pacchetto npm con un trusted publisher configurato ma che non ha mai completato una prima pubblicazione tramite quel canale, puntato su uno slug owner/repository ormai libero (repository rinominato, trasferito o rimosso).

Crea su GitHub un nuovo repository con esattamente quello slug. GitHub gli assegna un ID numerico diverso da quello originale, ma lo slug torna a esistere.

Configura nel repository un workflow di pubblicazione npm (lo stesso nome file che il maintainer originale avrebbe probabilmente usato) e lo esegue tramite GitHub Actions.

Il workflow genera un token OIDC che contiene lo slug “riconquistato”. L’attaccante lo invia all’endpoint di scambio di npm.

npm confronta solo lo slug con la configurazione registrata, trova corrispondenza e rilascia una credenziale di pubblicazione temporanea senza alcuna verifica aggiuntiva sull’identità del repository.

Con quella credenziale l’attaccante pubblica una versione malevola del pacchetto, ereditando reputazione, numero di download e, soprattutto, tutti i progetti che lo dichiarano come dipendenza.

Bloom Security sottolinea un aggravante specifico del 2026: gli agenti AI che risolvono dipendenze in autonomia tendono a scegliere sempre l’ultima versione pubblicata e raramente verificano la provenienza reale di un pacchetto, rendendo questo tipo di attacco alla supply chain ancora più efficace su pipeline automatizzate.

Timeline della scoperta e della correzioneLuglio 2025 — Trusted Publishing con OIDC diventa generalmente disponibile su npm.

6 giugno 2026 — Bloom Security segnala la vulnerabilità a GitHub tramite il programma HackerOne.

9 giugno 2026 — GitHub valida la segnalazione.

2 ottobre 2026 — GitHub pubblica il changelog con la correzione definitiva.

Come GitHub ha chiuso la fallaLa correzione agisce proprio sul punto debole: il periodo in cui una configurazione di trusted publisher esiste ma non è ancora stata “convalidata” da una pubblicazione reale.

Una nuova configurazione di trusted publisher ora scade dopo 48 ore se non viene usata per completare con successo una prima pubblicazione.

Dopo quella prima pubblicazione riuscita, la configurazione diventa vincolata all’identità immutabile del repository (l’ID numerico), non più solo al nome.

Qualsiasi modifica che cambi repository o identità del progetto richiede la creazione di una nuova relazione di fiducia, che riparte da una nuova finestra di 48 ore; le modifiche ordinarie non la riavviano.

npm ora rifiuta i token di Trusted Publishing generati da eventi issue_comment di GitHub Actions, estendendo una restrizione già esistente su pull_request_target — entrambi trigger storicamente abusati per far eseguire codice a partire da contenuti controllati da terzi (ad esempio un commento su una pull request).

Cosa deve controllare chi mantiene pacchetti npmAnche con la falla corretta, vale la pena fare un controllo preventivo sulle proprie configurazioni:

Verificare ogni trusted publisher configurato sui propri pacchetti e confermare che il repository collegato sia ancora effettivamente sotto il proprio controllo.

Dopo una rinomina, un trasferimento o la cancellazione di un repository, eliminare e ricreare il vincolo di trusted publisher sullo slug corretto, piuttosto che lasciarlo “in sospeso”.

Preferire trigger di pubblicazione più sicuri — push su tag, release o workflow_dispatch — evitando pull_request_target e issue_comment.

Bloccare le versioni delle dipendenze dove possibile e controllare con attenzione gli script postinstall, specialmente nei repository dove un agente AI installa pacchetti senza supervisione diretta.

Monitorare pubblicazioni inattese e verificare le attestazioni di provenance generate automaticamente da npm.

Il caso SlugFest è un buon promemoria generale, non solo per npm: qualsiasi sistema di trust basato su OIDC “federato” (PyPI ha un meccanismo molto simile) deve ancorare la fiducia a un identificatore immutabile, non a un nome che può essere liberato e rivendicato da chiunque. Chi gestisce pipeline di pubblicazione automatizzate, su npm o altrove, farebbe bene a verificare quale dei due modelli stia effettivamente usando.

Fonte: The Hacker News e Cyber Security News.

#sicurezza #github #supplychain #devops #dev #npm #cicd #nodejs

2

Caricamento...

0
1

Caricamento...