Sicurezza Tempo di lettura stimato: 11 min ·

Aggiornamento di sicurezza di Node.js: la Sua versione riceve ancora le patch?

Il 21 ottobre Node.js ha pubblicato patch di sicurezza per le release line 22, 24 e 26. Quali versioni sono sicure, perché Node.js 18 e 20 non ne riceveranno, e come verificare quale versione usa la Sua applicazione.

Finestra del browser con un ingranaggio e un segno di conferma — aggiornamento di sicurezza di Node.js

Il 21 ottobre Node.js ha pubblicato patch di sicurezza per le release line 22, 24 e 26. Quali versioni sono sicure, perché Node.js 18 e 20 non ne riceveranno, e come verificare quale versione usa la Sua applicazione.

Le patch le hanno ricevute solo le release line che hanno ancora supporto, e sicure sono le versioni 22.23.4, 24.22.1 e 26.12.1, o versioni più recenti sulla stessa release line. Node.js 18 e 20 hanno già raggiunto l’end of life, perciò in questo aggiornamento di sicurezza di Node.js una patch per esse non c’è e non ci sarà: se la Sua applicazione gira su una delle due, aggiornare significa passare a un’altra release line.

Mercoledì 21 ottobre il progetto Node.js ha pubblicato rilasci di sicurezza per tutte e tre le release line supportate, e lo stesso giorno PHP ha pubblicato patch di emergenza per le vulnerabilità che hanno preso il nome PHP2Shell, ma sono due eventi separati, di gravità diversa. Il rilascio di Node.js era stato annunciato in anticipo, il progetto ha valutato le sue vulnerabilità più gravi come alte, non come critiche, e nel comunicato non si menzionano né soluzioni temporanee né attacchi nell’ambiente reale. Questo non permette di rimandare l’aggiornamento, ma sposta l’attenzione: questa volta il rischio più grande non sta nel rilascio stesso, ma nelle versioni che non l’hanno ricevuto.

Che cosa ha corretto l’aggiornamento di sicurezza di Node.js di ottobre

Nel comunicato di Node.js sono elencate dieci vulnerabilità: quattro il progetto le ha valutate come alte, tre come medie e tre come basse, ma questa volta non ha pubblicato valutazioni CVSS, perciò questo articolo usa la stessa valutazione.

La più grave è CVE-2026-111497. Il progetto la chiama out-of-bounds write nel decodificatore Brotli, che consente l’esecuzione di codice da remoto (RCE), e la valuta come alta. Brotli è un formato di compressione il cui decodificatore è integrato in Node.js, e nelle note di rilascio la correzione è descritta come una modifica in questa libreria integrata. Per quale percorso la vulnerabilità sia raggiungibile, il comunicato non lo dice, e anche la descrizione della correzione da parte degli sviluppatori di Brotli parla solo del fatto che un flusso di dati non valido ora viene riconosciuto prima. Per questo qui non si nominano funzioni specifiche: l’unica cosa che si può dire con sicurezza è che un errore del decodificatore riguarda soprattutto le applicazioni che decomprimono dati Brotli da una fonte di cui non possono fidarsi.

Tre altre vulnerabilità riguardano il controllo dei certificati TLS, e non sono lo stesso caso. La prima, con valutazione alta, riguarda solo le release line 26 e 24: la hostname verification, il controllo del nome dell’host, si può aggirare se l’indirizzo IP è scritto con cifre a larghezza intera, per esempio 127.0.0.1. La seconda, anch’essa alta, riguarda tutte e tre le release line: il controllo si può aggirare se il nome dell’host si può leggere, in modo non rigoroso, come un indirizzo IP. La terza è media e riguarda anch’essa tutte e tre: una notazione IPv4 non standard permette a un nome DNS indicato nel certificato di autenticare un indirizzo IP. Nelle note di rilascio le correzioni sono formulate in breve: gli indirizzi IP scritti in forma inusuale ora vengono rifiutati, e a parte è stata corretta una regressione nella normalizzazione degli indirizzi IP. In tutti e tre i casi si parla del momento in cui Node.js agisce da client, cioè quando è esso stesso ad aprire una connessione cifrata verso un altro server, e non del momento in cui serve i propri visitatori.

La quarta vulnerabilità con valutazione alta è nella funzione dns.resolve, che troncava i nomi contenenti un carattere nullo. Fra le medie ci sono un errore nel riuso delle connessioni HTTP, in cui una risposta scritta sulla connessione prima dell’invio della richiesta poteva essere trattata come la risposta a quella richiesta, e un errore per cui la cache di casualità di crypto.randomUUID() e di randomInt() veniva salvata negli startup snapshot e in un unico file eseguibile, così che ogni processo ripeteva gli stessi valori. Tre vulnerabilità di valutazione bassa riguardano la gestione dei file ZIP e il Permission Model di Node.js.

L’errore della cache di casualità conviene capirlo con precisione, perché nel caso ordinario non ha alcun effetto. Riguarda solo i progetti che partono da uno startup snapshot costruito da loro, oppure che sono distribuiti come unico file eseguibile (single executable application, SEA), e lì significa che ogni processo avviato dallo stesso file ha ricevuto gli stessi valori «casuali». Se in un progetto del genere con crypto.randomUUID() o randomInt() si costruivano identificatori o codici temporanei, essi potevano ripetersi fra un processo e l’altro, perciò dopo la correzione Le conviene verificare se qualcuno di questi valori non sia usato là dove deve essere non indovinabile.

Il rilascio aggiorna anche diverse dipendenze integrate, a seconda della release line, c-ares, OpenSSL, SQLite e Undici, su cui si appoggia la funzione fetch integrata. Allo stesso modo è stato aggiornato il CA store, l’elenco integrato delle autorità di certificazione fidate, in relazione a un certificato intermedio eMudhra compromesso, e le connessioni TLS ora rifiutano le catene che contengono chiavi pubbliche bloccate.

Quali versioni sono sicure

Le versioni con la patch sono tre, una per ciascuna release line supportata: la 22.23.4, la 24.22.1 e la 26.12.1. Tutto ciò che, sulla propria release line, è più vecchio, è coinvolto. Non tutte e dieci le vulnerabilità riguardano ogni release line: la 26 ne ha tutte e dieci, la 24 ne ha otto e la 22 ne ha sette, perché due errori di valutazione bassa esistono solo sulla release line più recente e un errore TLS non riguarda la 22.

Aggiornare all’interno della release line è il passo più piccolo possibile, e di solito è anche la modifica più sicura che si possa fare in produzione. Anche quel passo, però, può cambiare il comportamento, e questa volta c’è un esempio concreto: la correzione del controllo TLS ora rifiuta gli indirizzi IP scritti in forma inusuale. Se un’applicazione, nelle connessioni verso un altro server, un tempo usava una notazione del genere, dopo l’aggiornamento la connessione può non riuscire. È un buco di sicurezza che è stato chiuso, non un errore nuovo, ma Le conviene saperlo prima dell’aggiornamento, non dopo.

La release line conta più del numero di versione

Fino a Node.js 26 ogni major version attraversa un solo ciclo: prima è la versione Current, poi le versioni con numero pari ricevono il supporto a lungo termine attivo (Active LTS), quindi passano a Maintenance LTS, in cui ricevono solo correzioni di errori critici e patch di sicurezza, e alla fine il supporto cessa del tutto, mentre le versioni con numero dispari, fino alla release line 25, il supporto a lungo termine non lo ricevevano. Da Node.js 27 il ciclo cambia: secondo il calendario dei rilasci ogni release line riceverà il supporto a lungo termine, e per tutti i 30 mesi di quel supporto resterà nella fase attiva, senza Maintenance LTS. Il progetto scrive esso stesso che le applicazioni di produzione devono usare solo versioni Active LTS o Maintenance LTS.

Per le release line attuali i prossimi cambi di fase avvengono in due date. Secondo il calendario dei rilasci di Node.js la release line 24 è passata a Maintenance LTS il 20 ottobre, il giorno prima del rilascio di sicurezza, e la 26 riceverà il supporto a lungo termine il 28 ottobre. La release line 22 è in Maintenance LTS dal 21 ottobre 2025 e raggiungerà l’end of life il 30 aprile 2027, mentre la 24 lo raggiungerà il 30 aprile 2028.

Il senso pratico è semplice: la domanda «abbiamo l’ultima versione» da sola non dice granché, mentre è utile la domanda «su quale release line siamo, e fino a quale data riceverà le patch». La prima cambia risposta ogni mese, la seconda una volta ogni paio d’anni, e proprio per questo la seconda è facile da dimenticare.

Node.js 18 e 20: non ci sarà una patch di sicurezza

Nel comunicato di Node.js c’è una frase che, questa volta, conta più di tutte e dieci le vulnerabilità: le versioni che hanno raggiunto l’end of life sono sempre coinvolte quando esce un rilascio di sicurezza. Una patch, per esse, non si pubblica né ora né più tardi, perché una release line che ha raggiunto l’end of life non riceve più alcun rilascio.

Secondo il calendario dei rilasci la release line 16 ha raggiunto l’end of life l’11 settembre 2023, la 19 il 1° giugno 2023, la 18 il 30 aprile 2025 e la 20 il 30 aprile 2026. L’ultima data è la più importante: la release line 20 ha raggiunto l’end of life poco meno di sei mesi fa, e un progetto avviato su di essa può ancora funzionare senza alcun problema visibile. Proprio questo rende la situazione insidiosa, perché nulla nel suo funzionamento indica che le patch di sicurezza non le spettano più.

Per le aziende che non possono passare in fretta a una release line supportata, il comunicato di Node.js menziona una possibilità: il supporto commerciale per le versioni oltre la fase Maintenance LTS lo offrono i partner dell’OpenJS Ecosystem Sustainability Program. È un servizio a pagamento, ed è una soluzione temporanea, non un sostituto del passaggio.

Come verificare quale Node.js usa la Sua applicazione

La verifica richiede minuti, ma c’è un punto in cui è facile sbagliarla: la versione di Node.js che mostra il terminale non è sempre la stessa con cui lavora l’applicazione.

Hosting con cPanel: la versione in uso la mostra la sezione Software → Setup Node.js App, dove ogni applicazione ha la propria riga e la versione si sceglie da un elenco. Nell’elenco ci sono solo le versioni che il fornitore di hosting ha installato sul server. Il comando node -v su un hosting di questo tipo può mostrare una versione diversa da questa impostazione, perciò guardi proprio la riga che La riguarda.

Server proprio: il comando node -v mostra la versione che viene per prima nel percorso di sistema, ma un gestore dei processi, per esempio PM2 o un servizio systemd, può avviare il programma con un eseguibile del tutto diverso. La risposta di cui ci si può fidare è quella che il processo riferisce di sé: il valore di process.version, per esempio scritto nel log al momento dell’avvio.

Container: in un ambiente Docker la versione la decide la container image, non la macchina host. Una container image costruita prima del 21 ottobre non contiene la patch, indipendentemente da quante volte il container sia stato riavviato, perciò la container image va ricostruita con una base image aggiornata.

Se non ha accesso: allora la domanda va al fornitore di hosting o allo sviluppatore che lo mantiene. La formulazione che accorcia lo scambio di messaggi: «Quale versione di Node.js usa la nostra applicazione? Sulla propria release line è almeno la 22.23.4, la 24.22.1 o la 26.12.1? Se è su una release line in end of life, per esempio la 18 o la 20, quando è previsto il passaggio?»

Che cosa fare oggi

L’ordine di oggi è questo: prima aggiornare Node.js alla versione con la patch sulla propria release line e riavviare ogni processo che la usa, poi ricostruire tutto ciò in cui il runtime è integrato, e solo dopo pianificare il passaggio per i progetti che girano su release line in end of life.

Per prima cosa, aggiorni all’interno della release line: alla 22.23.4, alla 24.22.1 o alla 26.12.1, a seconda di quella su cui si trova. Nel caso dell’hosting lo fa il fornitore, e il Suo compito è accertarsi che l’applicazione usi la versione aggiornata.

In secondo luogo, riavvii i processi: un processo che è già in esecuzione continua a usare il Node.js con cui è stato avviato, e sostituire il file sul disco non lo tocca. Lo stesso valeva per PHP2Shell: il package è stato sostituito, ma il processo vecchio continua a lavorare con il codice vecchio.

In terzo luogo, ricostruisca ciò in cui il runtime è integrato: le container image Docker vanno ricostruite con una base image aggiornata. Se distribuisce il programma come unico file eseguibile (SEA), dentro quel file c’è Node.js stesso, perciò aggiornare la versione installata sul sistema non lo tocca, e il file va ricostruito con la versione che contiene la patch. Lo stesso vale per gli startup snapshot, che sono toccati dall’errore della cache di casualità.

In quarto luogo, se è sulla release line 18 o sulla 20, pianifichi il passaggio: è un lavoro più grande dell’aggiornamento all’interno della release line, perciò Le conviene cominciare adesso, e l’ordine è descritto nella sezione successiva.

Come passare da Node.js 18 o 20

Il passaggio fra major version non è il lavoro di un solo comando, e conviene farlo in sequenza. Prima si sceglie l’obiettivo. Nella maggior parte dei casi è la release line 24, che riceverà le patch fino al 30 aprile 2028; la release line 22 è una scelta sensata solo se qualche dipendenza importante non supporta ancora la 24, perché il supporto della release line 22 finisce un anno prima.

Poi vanno trovati tutti i punti in cui il progetto fissa la propria versione di Node.js, perché quasi sempre sono più d’uno: il campo engines di package.json, i file .nvmrc o .node-version, la base image del Dockerfile, la configurazione dell’ambiente di continuous integration (CI) e l’impostazione nel pannello di hosting. Se se ne cambia solo una parte, ambienti diversi eseguono versioni diverse, e gli errori compaiono proprio dove è più difficile trovarli.

Poi il progetto va installato di nuovo nell’ambiente di test, con la versione nuova, e vanno eseguiti i test. Un’attenzione particolare spetta ai package che contengono codice compilato: sono costruiti per una versione specifica di Node.js, perciò dopo il passaggio può essere necessario ricostruirli o aggiornarli. Per ogni major version Node.js pubblica un elenco delle modifiche, nel quale sono segnate a parte quelle che possono rompere il codice esistente, e Le conviene leggerlo prima del passaggio, non dopo.

Solo allora viene l’ambiente di produzione: il cambio di versione, il riavvio dei processi e la verifica che process.version mostri la versione nuova. La versione vecchia può restare disponibile per qualche giorno, nel caso si debba tornare indietro, ma non più a lungo, perché è proprio la versione per la quale non ci sarà più una patch.

Che cosa non si aggiorna insieme a Node.js

Aggiornare Node.js ripara il runtime stesso e le librerie che vi sono integrate, ma non tutto ciò che l’applicazione usa, e proprio qui restano più spesso i buchi che nessuno vede.

Package installati separatamente: se il progetto, fra le proprie dipendenze, usa il package undici di npm e non il fetch integrato, quel package sta nella cartella node_modules del progetto, e un rilascio di Node.js non lo tocca. Lo stesso vale per tutte le altre dipendenze: le aggiorna il gestore dei package, e solo quando qualcuno lo avvia.

CA store: per impostazione predefinita Node.js non usa l’elenco delle autorità di certificazione del sistema operativo, ma il proprio CA store integrato, e nella documentazione si dice che è una copia dell’elenco di Mozilla, fissata al momento del rilascio. Perciò una modifica come la reazione di questo rilascio al certificato intermedio eMudhra compromesso arriva al programma solo insieme all’aggiornamento del runtime, e non insieme agli aggiornamenti del sistema operativo, a meno che il programma non sia configurato apposta per usare l’elenco del sistema.

Come non lasciarsi sfuggire il prossimo rilascio

I rilasci di sicurezza di Node.js vengono annunciati in anticipo sulla pagina della sicurezza del progetto, con l’indicazione del giorno previsto per il rilascio, e questa volta è andata proprio così. Questo mercoledì, quindi, non è stato una sorpresa per chi quella pagina la sorveglia: l’aggiornamento si poteva mettere in agenda prima, invece di cercare il tempo il giorno stesso.

In pratica questo significa che qualcuno deve essere responsabile di questa sorveglianza. Sull’hosting gestito lo fa il fornitore, ma sul proprio server, o su un progetto che il proprio team mantiene, conviene sapere chi segue i comunicati del progetto, chi decide l’aggiornamento e chi verifica che, dopo l’aggiornamento, tutto funzioni. Se a queste domande la risposta è «nessuno in particolare», è proprio lì che sta il rischio più grande, e non in una delle dieci vulnerabilità.

Se Node.js per Lei è solo un build tool

Su molti siti web Laravel e WordPress Node.js sul server non gira affatto: fa funzionare Vite o un build tool simile, che dai sorgenti prepara i file CSS e JavaScript e poi si ferma. In quel caso la situazione è diversa da un’applicazione che serve essa stessa le richieste, perché il processo di build non risponde alle richieste da internet e non decomprime dati che gli mandano visitatori sconosciuti.

Diversa non significa che non conti. I build tool lavorano sui computer degli sviluppatori e nell’ambiente di continuous integration, scaricano package e aprono connessioni verso altri server, e le descrizioni delle vulnerabilità sono troppo brevi per dire con sicurezza quali di questi percorsi siano coinvolti. Aggiornare Node.js conviene anche lì, solo nell’ordine giusto: prima i server sui quali Node.js lavora online, poi i computer degli sviluppatori e l’ambiente di CI.

C’è anche una seconda ragione, che con questa settimana non c’entra. L’ambiente di build spesso resta sulla versione di Node.js con cui il progetto un tempo è stato avviato, e poi un giorno una versione nuova di uno strumento semplicemente rifiuta di lavorarci. Il passaggio a una release line supportata avviene allora di fretta e in un momento che non va bene, perciò è più facile farlo adesso, finché è un lavoro pianificato.

Che cosa ha significato sul nostro hosting

Il nostro hosting gestito è un posto sul nostro server, e ogni cliente vi sceglie la versione attraverso il pannello di hosting. Sul nostro server le release line 22 e 24 di Node.js girano già con le versioni che contengono la patch, la 22.23.4 e la 24.22.1. Ai clienti i cui progetti usano queste release line non c’è nulla da fare, tranne accertarsi che il processo, dopo l’aggiornamento, sia stato riavviato.

Va detta con franchezza anche l’altra faccia. Sul server, fra le scelte, restano disponibili anche release line che hanno raggiunto l’end of life, e per esse una patch non c’è — né sul nostro server, né su quello di qualcun altro, perché Node.js una patch del genere non la pubblica. Se per il Suo progetto ne è stata scelta una, aggiornare significa passare alla release line 22 o alla 24, ed è meglio farlo insieme a una verifica che, dopo il passaggio, tutto funzioni come prima.

Il nostro hosting gestito parte da 45 € al mese, e i runtime mantenuti sono parte di ciò per cui, in quella cifra, si paga. Se la Sua applicazione gira ancora su Node.js 18 o 20, parliamo del passaggio, prima che a imporlo sia il giorno di un prossimo rilascio di sicurezza.

FAQ

Domande frequenti.

Node.js: quale versione è sicura?

Sicure sono la 22.23.4, la 24.22.1 e la 26.12.1, o versioni più recenti sulla stessa release line. Tutto ciò che, sulla propria release line, è più vecchio, è coinvolto. Per le versioni la cui release line ha raggiunto l’end of life, per esempio Node.js 18 e 20, una versione sicura non esiste affatto, perché per esse non si pubblicano patch.

Ho Node.js 18 o 20. Che cosa devo fare?

Entrambe le release line hanno raggiunto l’end of life: la 18 il 30 aprile 2025, la 20 il 30 aprile 2026. Una patch per esse non c’è e non ci sarà, perciò l’unica via è il passaggio a una release line supportata. La release line 24 riceverà le patch fino al 30 aprile 2028, la 22 fino al 30 aprile 2027. Il passaggio Le conviene provarlo prima in un ambiente di test.

Questo aggiornamento di sicurezza di Node.js è la stessa cosa di PHP2Shell?

No. Entrambi gli eventi sono stati il 21 ottobre, ma sono separati. PHP2Shell erano due vulnerabilità critiche nel PHP stesso. Il rilascio di sicurezza di Node.js era stato annunciato in anticipo, le sue vulnerabilità più gravi sono valutate come alte, e nel comunicato non si menzionano attacchi nell’ambiente reale.

Basta aggiornare Node.js, se l’applicazione è già in esecuzione?

No, il processo va riavviato. Un processo che è già in esecuzione continua a usare il Node.js con cui è stato avviato. Se l’applicazione è in una container image Docker, oppure è distribuita come unico file eseguibile (SEA), dentro c’è Node.js stesso, e va ricostruita con la versione che contiene la patch.

Sul nostro sito web Laravel o WordPress Node.js serve solo a costruire con Vite. Questo ci riguarda?

Meno di quanto riguardi un’applicazione che serve essa stessa le richieste, perché il processo di build non risponde alle richieste da internet. I build tool, però, scaricano package e aprono connessioni verso altri server, perciò conviene aggiornare Node.js anche sui computer degli sviluppatori e nell’ambiente di continuous integration (CI), ma solo dopo i server.

Ci sono soluzioni temporanee, se non si può aggiornare subito?

Nel comunicato di Node.js le soluzioni temporanee non sono menzionate. L’unica raccomandazione è usare una versione supportata, secondo il calendario dei rilasci. Per le versioni che hanno raggiunto l’end of life, Node.js menziona il supporto commerciale offerto dai partner dell’OpenJS Ecosystem Sustainability Program.

Come si vede quale versione di Node.js usa un’applicazione sull’hosting con cPanel?

Nella sezione Software → Setup Node.js App, dove ogni applicazione ha la propria riga con la versione scelta. Il comando node -v nel terminale può mostrare una versione diversa dall’impostazione dell’applicazione, perciò guardi proprio la riga dell’applicazione.

SERVIZIO CORRELATO
Hosting gestito e infrastruttura server

Server, hosting e manutenzione nell’UE — a Francoforte, Helsinki o Riga, con monitoraggio 24/7. Gestione completa: aggiornamenti, sicurezza e prestazioni, backup automatici con ripristino verificato, certificati SSL, CDN e protezione DDoS. Migriamo dal Suo hosting attuale senza interruzioni di servizio e scaliamo in base al carico.

Scopra di più