Sei pacchetti npm, un nome quasi identico a un progetto scaricato oltre un milione di volte al mese, e in fondo alla catena un impianto capace di aprire sessioni SSH, leggere la clipboard e rovistare tra i wallet crypto della vittima. È l’ultima campagna di supply chain attribuita a gruppi legati alla Corea del Nord, documentata da JFrog Security Research il 30 giugno e ancora attiva nei repository pubblici a inizio luglio. Non è un incidente isolato: è l’ennesima iterazione di una macchina offensiva, quella riconducibile all’ecosistema Lazarus/Contagious Interview, che negli ultimi anni ha trasformato l’npm registry in un vettore di spionaggio e furto di criptovalute su scala industriale.
Un travestimento quasi perfetto
I ricercatori di JFrog hanno individuato due pacchetti “entry point”, rollup-packages-polyfill-core e rollup-runtime-polyfill-core, costruiti per somigliare in tutto e per tutto al legittimo rollup-plugin-polyfill-node: stesso tipo di README (“A modern Node.js polyfill for your Rollup bundle”), stesso link a repository e homepage puntati al progetto originale su GitHub, persino porzioni di codice del plugin reale copiate all’interno del pacchetto malevolo prima della logica dannosa. Il progetto legittimo conta circa 295.000 download settimanali e oltre 1,2 milioni nell’ultimo mese: un bersaglio ideale per un attacco che punta sulla somiglianza superficiale, non sul typosquatting grossolano.
Il dettaglio tecnico più rilevante è che solo l’entry point CommonJS (dist/index.js) contiene la backdoor: le versioni ESM restano pulite, un accorgimento che complica le analisi automatiche basate su un singolo file di ingresso.
La catena d’infezione, passo dopo passo
All’importazione del pacchetto, una funzione dal nome innocuo (ValidateSvgModule) decodifica una stringa base64 che nasconde il comando npm install swift-parse-stream --no-save --silent --no-audit --no-fund, eseguito in silenzio tramite child_process.spawn. Il secondo pacchetto, quirky-token, viene installato allo stesso modo dal gemello rollup-runtime-polyfill-core.
Questi pacchetti di secondo stadio si presentano come utility di sanitizzazione SVG, e in gran parte lo sono davvero: rimuovono tag <script>, minificano il markup. Ma in coda al file, una funzione getPlugin() effettua una richiesta verso un endpoint su jsonkeeper.com, estrae un campo JSON chiamato model e lo passa direttamente a eval(). Il codice malevolo, quindi, non risiede mai nei file pubblicati sul registry: vive su un servizio di hosting JSON esterno, invisibile a qualunque analisi statica del pacchetto.
Il payload recuperato da JSONKeeper effettua per primo un controllo ambientale, uscendo silenziosamente se rileva variabili tipiche di Codespaces, CodeSandbox, Vercel, AWS Lambda, Google Cloud, Azure Functions, Docker, Render o sandbox di analisi — un chiaro tentativo di colpire solo workstation di sviluppatori reali ed evitare l’esposizione in ambienti di test automatizzati. Superato il controllo, installa axios e socket.io-client e scarica da un IP grezzo (216.126.236.244) un blob cifrato in AES-256-CBC (chiave derivata via scryptSync), lo decifra, lo scrive in una directory temporanea come file pack e lo esegue con node pack.
Controllo remoto, furto wallet e sorveglianza della clipboard
Il modulo pack altro non è che un loader per almeno quattro componenti distinti, ricostruiti da JFrog in ambiente sandbox: scdata.js, un modulo di accesso remoto che installa ssh2, node-pty e librerie di cattura schermo/input, offrendo all’operatore sessioni terminali interattive (PowerShell su Windows, zsh altrove), sessioni SSH, screenshot, movimento del mouse e digitazione simulata tramite @nut-tree-fork/nut-js; ldata.js, dedicato al furto di dati da browser e wallet crypto, che tenta l’esfiltrazione di file come Login Data, Web Data e lo storage delle estensioni di wallet noti (incluso MetaMask, identificato tramite i suoi ID di estensione); un file collector che scandaglia il filesystem alla ricerca di chiavi SSH, file .env, cronologia di editor come VS Code, Cursor e Windsurf, e directory di configurazione di strumenti AI (.claude, .gemini, .cursor); infine un modulo di monitoraggio della clipboard, che invia ogni nuovo contenuto copiato — password, seed phrase, token — a un endpoint dedicato.
La combinazione di queste capacità va ben oltre il semplice furto di credenziali una tantum: garantisce all’attaccante un accesso interattivo e persistente alla macchina compromessa, tipico degli impianti usati da attori state-sponsored per operazioni di raccolta informativa prolungata, non solo per il cash-out rapido tipico del cybercrime finanziario puro.
Il contesto: non è la prima volta
Questa campagna si inserisce in un pattern già documentato. Ad aprile 2026 la società Panther aveva descritto una campagna sostenuta con 108 pacchetti npm malevoli distribuiti in 261 versioni, veicolo dei malware BeaverTail e OtterCookie, entrambi associati al cluster Contagious Interview — l’insieme di operazioni nordcoreane che si finge selezione del personale per convincere sviluppatori a clonare repository infetti come parte di un finto colloquio tecnico. Nello stesso periodo, Google aveva collegato attori nordcoreani anche a un dirottamento di un progetto open source molto diffuso, portato a termine dopo settimane di lavoro di ingegneria sociale ai danni del maintainer. Il filo conduttore è sempre lo stesso: colpire la fiducia implicita che sviluppatori e pipeline CI/CD ripongono nelle dipendenze open source.
Due righe per i difensori
Per i team di sicurezza e gli sviluppatori, la lezione operativa è chiara: la somiglianza del nome non è un indicatore affidabile di legittimità, e i controlli automatici basati su pattern di typosquotting classico (distanza di edit, caratteri sostituiti) non intercettano questo tipo di masquerading semantico. Chi ha installato uno dei pacchetti elencati dovrebbe considerare la macchina compromessa, ruotare tutte le credenziali (npm, GitHub, cloud, SSH, wallet) e verificare la presenza di processi o file residui nelle directory temporanee. Vale la pena ricordare che gran parte della logica dannosa non è mai stata pubblicata sul registry npm: bloccare gli indicatori di rete elencati sotto è quindi essenziale quanto rimuovere i pacchetti stessi.
Indicatori di compromissione
Pacchetti npm malevoli:
rollup-packages-polyfill-core
rollup-runtime-polyfill-core
swift-parse-stream
quirky-token
react-icon-svgs
rollup-plugin-polyfill-connect
Indicatori di rete:
hxxps[:]//www[.]jsonkeeper[.]com/b/3P9BF
hxxp[:]//216[.]126[.]236[.]244/api/service/98cb54c0b4ac259d30c9c1ca1ae87c68
hxxp[:]//216[.]126[.]236[.]244/api/service/makelog
hxxp[:]//216[.]126[.]236[.]244/api/service/process/
hxxp[:]//216[.]126[.]236[.]244:4801
hxxp[:]//216[.]126[.]236[.]244:4806/upload
hxxp[:]//216[.]126[.]236[.]244:4809/upload
hxxp[:]//216[.]126[.]236[.]244:4809/cldbs
Indicatori host:
/pack
/scdata
/ldata
vhost.ctl
Comandi/comportamenti sospetti:
npm install swift-parse-stream --no-save --silent --no-audit --no-fund
npm install quirky-token --no-save --silent --no-audit --no-fund
node pack
node scdata
node ldata