Il worm che nel giugno scorso avevamo raccontato con il nome Shai-Hulud è tornato, e questa volta ha centrato un bersaglio di primissimo piano dell'ecosistema JavaScript. Il 4 agosto 2026 una versione malevola di keyv — una libreria di caching scaricata milioni di volte a settimana e usata come dipendenza da innumerevoli progetti — ha dato il via a una nuova ondata di propagazione automatica che ha avvelenato centinaia di pacchetti npm. I numeri variano a seconda di chi conta, perché il registro cambiava troppo in fretta: SafeDep ha verificato inizialmente 353 versioni malevole su 79 nomi di pacchetto, salite poi a 1.684 versioni su 420 nomi legati a nove organizzazioni; altre società di sicurezza riportano cifre diverse. Il dato che conta non è il totale esatto ma il meccanismo: il worm si spostava da un'organizzazione all'altra ogni due-sette minuti, completando l'intera raffica di pubblicazioni in circa mezz'ora.
Come funziona: furto di credenziali e "dead-man's switch"
La versione compromessa (keyv@6.0.0) aggiungeva uno script preinstall — eseguito automaticamente durante l'installazione del pacchetto — che avviava un bundle di furto credenziali all'interno degli ambienti degli sviluppatori e dei sistemi di integrazione continua (CI). Il payload cerca e sottrae di tutto: token GitHub e npm, credenziali cloud AWS/GCP/Azure, secret Kubernetes, token HashiCorp Vault, chiavi SSH, credenziali di database, file di stato Terraform, database dei password manager, token Slack e Stripe. Non solo: legge la memoria dei runner di GitHub Actions per estrarre i secret mascherati, una tecnica che vanifica il mascheramento dei log. Con le credenziali di pubblicazione npm rubate, il worm si ripubblica in nuovi pacchetti — da qui la propagazione a catena.
L'aspetto più insidioso è un interruttore "dead-man": il malware installa un watcher che interroga le API di GitHub ogni 60 secondi con il token rubato e, nel momento in cui rileva che quel token è stato revocato, esegue un handler predisposto dall'attaccante. In pratica, la reazione istintiva del difensore — revocare subito le chiavi compromesse — è proprio ciò che innesca la trappola. SafeDep è esplicita: bisogna prima individuare e neutralizzare il watcher, e solo dopo ruotare token e chiavi.
C'è infine una novità che segna i tempi: il repository keyv conteneva anche hook per Claude Code e Visual Studio Code (file .claude/settings.json e .vscode/tasks.json con esecuzione all'apertura della cartella), pensati per far partire il payload quando uno sviluppatore apre o "si fida" del workspace. Entrambi gli ambienti richiedono la fiducia esplicita dell'utente prima di eseguire task automatici, quindi non scattano in ogni configurazione — ma è la conferma che gli attaccanti stanno progettando la supply chain avendo in mente anche gli editor con agenti IA. Va aggiunto un elemento importante per non cadere nel falso senso di sicurezza: la release avvelenata portava una provenance OIDC/SLSA valida, perché era passata attraverso il normale workflow di rilascio del progetto su GitHub Actions. L'attestazione certificava correttamente il processo di build, ma non poteva garantire che il sorgente in ingresso fosse pulito.
Cosa significa per le aziende italiane
Chi non scrive software potrebbe pensare che sia un problema di nicchia per sviluppatori. Non lo è. keyv è una dipendenza "transitiva" tipica: quasi nessuno la installa di proposito, ma finisce dentro migliaia di applicazioni web e servizi aziendali attraverso altre librerie. Qualsiasi organizzazione italiana che sviluppa in casa applicazioni Node.js — dalle software house alle banche, dalle web agency ai team digitali della PA — potrebbe aver eseguito una versione avvelenata su una workstation o, peggio, su un runner CI/CD con accesso privilegiato ai sistemi di produzione. E qui sta il punto dolente: un token di CI compromesso può valere molto più di una singola macchina, perché apre le porte del deployment. Il fatto che il worm punti esplicitamente ai secret dei runner segnala una maturità preoccupante: l'obiettivo non è più il singolo sviluppatore, ma la pipeline che porta il codice in produzione.
Il contesto normativo
L'attacco cade mentre l'Europa costruisce l'impianto di regole sulla sicurezza del software. La direttiva NIS2 impone ai soggetti essenziali e importanti di presidiare la sicurezza della catena di approvvigionamento, comprese le dipendenze software; il Cyber Resilience Act (Regolamento UE 2024/2847), i cui obblighi principali si applicheranno dalla fine del 2027, renderà obbligatoria per i prodotti con elementi digitali la gestione delle vulnerabilità lungo tutto il ciclo di vita e la software bill of materials (SBOM). Un incidente di questo tipo, se comporta l'esposizione di dati personali attraverso credenziali rubate, può inoltre far scattare gli obblighi di notifica del GDPR al Garante e — per i soggetti in perimetro — ad ACN/CSIRT Italia. La SBOM, spesso vista come adempimento burocratico, in un caso così è esattamente lo strumento che permette di rispondere in minuti alla domanda "uso keyv, e in quale versione?".
Cosa fare subito
- Verificare lockfile e versioni risolte (non i tag
latest, che sono stati manipolati): confrontarle con la lista dei pacchetti e delle versioni compromesse. Aggiornare non basta selatestpunta ancora a una versione malevola. - Prima di ruotare le chiavi, cercare e rimuovere il watcher di revoca (percorso tipico
~/.config/gh-token-monitor/): la rotazione è l'innesco del dead-man's switch. - Trattare come compromessa ogni workstation o runner CI che abbia eseguito una versione affetta; ruotare in modo controllato token GitHub/npm, credenziali cloud, chiavi SSH e secret di pipeline.
- Disabilitare gli script di lifecycle non necessari in fase di installazione; npm 12 li blocca per default, ma le versioni precedenti restano esposte.
- Controllare i repository per la presenza di file
.claude/settings.jsone.vscode/tasks.jsonsospetti con esecuzione all'apertura della cartella. - Adottare, dove possibile, il pinning delle dipendenze con hash e generare una SBOM per gli applicativi in produzione.