In una specie di deja vu di log4j, attori malevoli hanno violato alcuni dei pacchetti più critici dell’ecosistema npm, iniettando codice malevolo in librerie con oltre 2,6 miliardi di download settimanali. L’attacco, definito da molti come il più esteso attacco supply chain della storia, ha sfruttato un sofisticato phishing mirato per compromettere l’account di un maintainer di fiducia, Josh Junon, noto come “qix” nella community npm.
Tutto è iniziato con un’email subdola, apparentemente innocua, inviata da support@npmjs.help — un dominio che imita in modo persuasivo il legittimo npmjs.com. Il messaggio avvertiva i maintainer che i loro account sarebbero stati bloccati entro il 10 settembre se non avessero aggiornato le credenziali di autenticazione a due fattori. Una scusa plausibile, in linea con le migliori pratiche di sicurezza, ma che nascondeva un’intenzione malevola. Chi ha cliccato sul link è stato indirizzato a una pagina di login fasulla, progettata per rubare nome utente e password, inviandoli in tempo reale a un server controllato dagli aggressori.
Una volta ottenuto l’accesso, gli hacker hanno modificato diverse versioni di pacchetti npm estremamente popolari, tra cui chalk
, debug
, ansi-styles
e altri, inserendo codice malevolo direttamente nei file index.js. Il malware, una volta eseguito nel browser delle vittime, agisce come un intercettore silenzioso: monitora le transazioni di criptovalute su reti come Ethereum, Bitcoin, Solana, Tron, Litecoin e Bitcoin Cash, sostituendo gli indirizzi di destinazione con portafogli controllati dagli attacker prima che la transazione venga firmata dall’utente.
Il meccanismo di iniezione sfrutta tecniche di hooking di funzioni JavaScript fondamentali come fetch
, XMLHttpRequest
e le API dei wallet più diffusi (window.ethereum, Solana, ecc.). In pratica, il codice altera le risposte di rete e manipola ciò che l’utente vede e firma, senza lasciare tracce evidenti. Come ha sottolineato Charlie Eriksen di Aikido Security, “la pericolosità risiede nel fatto che opera a più livelli: altera il contenuto mostrato sui siti web, manomette le chiamate API e manipola ciò che le app degli utenti credono di star firmando.”
Tuttavia, non tutti i progetti che utilizzano queste dipendenze sono necessariamente vulnerabili. Come ha precisato Andrew MacPherson di Privy, perché un’applicazione sia colpita devono verificarsi condizioni specifiche: un’installazione fresca durante la finestra temporale dell’attacco (dalle 9:00 alle 11:30 ET dell’8 settembre), la generazione di un package-lock.json in quel lasso di tempo, e la presenza delle versioni modificate nelle dipendenze dirette o transitive.
La vicenda fa emergere nuovamente le profonde domande sulla sicurezza dell’open source. Molti dei pacchetti coinvolti sono mantenuti da sviluppatori volontari, spesso senza risorse dedicate per la sicurezza. La compromissione di un singolo maintainer può innescare un effetto domino in grado di colpire milioni di utenti e aziende in tutto il mondo.
Ad ogni modo, sappiamo bene quanto il lavoro dell’open source resti comunque insostituibile, rispetto a pochi contributi proprietari, per svolgere semplici compiti largamente necessari. Considerando inoltre che attacchi di questo genere, non di rado bypassano anche le impetuose muraglie cyber delle imponenti strutture closed-software di aziende proprietarie.
Questo non è il primo attacco del genere — solo a luglio, eslint-config-prettier (30 milioni di download settimanali) era stato violato con tecniche simili — ma la scala è senza precedenti. E dimostra come il browser sia ormai un surface attack primario, non solo per il furto di credenziali, ma per la manipolazione di transazioni finanziarie e la violazione di interi ecosistemi software.
La response di npm è stata rapida: molte versioni malevole sono state rimosse, incluso quella di debug
, che da sola conta 357 milioni di download settimanali. Ma il danno alla fiducia potrebbe essere più duraturo. In un mondo sempre più dipendente da package open source, la sicurezza della supply chain software non è più un problema tecnico marginale, ma una questione centrale per la resilienza digitale globale.
Package | Version |
---|---|
backslash | 0.2.1 |
chalk-template | 1.1.1 |
supports-hyperlinks | 4.1.1 |
has-ansi | 6.0.1 |
simple-swizzle | 0.2.3 |
color-string | 2.1.1 |
error-ex | 1.3.3 |
color-name | 2.0.1 |
is-arrayish | 0.3.3 |
slice-ansi | 7.1.1 |
color-convert | 3.1.1 |
wrap-ansi | 9.0.1 |
ansi-regex | 6.2.1 |
supports-color | 10.2.1 |
strip-ansi | 7.1.1 |
chalk | 5.6.1 |
debug | 4.4.2 |
ansi-styles | 6.2.2 |