L'account GitHub del maintainer jaredwray è stato compromesso il 4 agosto 2026, portando alla pubblicazione di keyv@6.0.0 e di altri dieci pacchetti npm contenenti malware con valida attestazione OIDC provenance e firma SLSA. La tecnica evidenzia un paradosso strutturale: le firme crittografiche attestano fedelmente una build il cui sorgente o contesto di workflow è già stato manomesso.
Gli attaccanti hanno sfruttato un vettore di esecuzione ancora poco monitorato: i file di configurazione degli agent AI integrati in ambienti di sviluppo come VS Code e Claude Code. Questi file non vengono analizzati dagli scanner di dipendenze, permettendo l'esecuzione di codice malevolo al semplice apertura di una cartella di progetto.
- Undici pacchetti npm, inclusi keyv@6.0.0 e cacheable@2.5.1, sono stati pubblicati con payload identici via hook preinstall il 4 agosto 2026.
- I file .claude/settings.json e .vscode/tasks.json nel repository attivano esecuzione automatica su folder open, invisibile agli strumenti tradizionali.
- Le attestazioni SLSA e la provenance OIDC erano valide: il workflow GitHub Actions ha firmato artefatti costruiti da sorgente compromessa.
- Il C2 utilizza uno smart contract Ethereum aggiornabile, con un token revocation watcher che reagisce alla rotazione delle credenziali.
La compromissione del maintainer e la pubblicazione firmata
Alle 5:00 ET del 4 agosto 2026, file malevoli sono stati pushati sul branch main del repository keyv. Quattro minuti dopo, un commit con badge verified ha aggiunto hook di persistenza per Claude Code e VS Code, con autore claude@users.noreply.github.com e messaggio "chore: update config". Alle 5:35 ET, keyv@6.0.0 è stato pubblicato su npm.
Snyk ha analizzato staticamente i tarball, confermando che tutti contenevano setup.mjs (29.918 byte) e Math_Symbol.js (727.680 byte) con hash identici. Alle 11:16 UTC, otto release malevole erano ancora taggate latest su npm: tre erano già state rimosse (flat-cache, cacheable-request, cache-manager).
Il meccanismo di esecuzione è dichiarato esplicitamente nel package.json: "preinstall": "node setup.mjs". npm esegue automaticamente questo hook durante l'installazione, senza richiedere interazione utente o importazione del modulo nell'applicazione.
Il blind spot dei file AI agent: codice che gira senza installazione pacchetto
Il repository compromesso conteneva .claude/settings.json con un hook SessionStart che punta a un loader script, e .vscode/tasks.json con un task "Environment Setup" configurato con "runOn": "folderOpen". Kodem Security ha evidenziato il problema: "Agent configuration files execute code, they live in repositories, and no dependency scanner reads them."
La stessa fonte ha sottolineato la portata del pattern: "The structural significance of the technique goes beyond any individual attack". A differenza del payload npm, che richiede almeno un'installazione, questi file attivano esecuzione al momento in cui uno sviluppatore apre il progetto nell'IDE o nell'agent AI.
Il worm ha propagato attivamente questi file di configurazione, commettendoli fino a 50 branch per repository vittima. Questo meccanismo di self-propagation amplifica la superficie di attacco oltre la sola installazione del pacchetto malevolo.
Provenance e SLSA: quando la firma diventa arma dell'attaccante
Un elemento distintivo di questo attacco è la presenza di attestazioni di provenance valide. Il manifest npm identifica GitHub Actions come trusted publisher, con workflow che ha costruito artefatti da sorgente già compromessa. Snyk Security Research ha formulato il principio con chiarezza: "Provenance can faithfully attest a build whose source or workflow context has already been compromised."
Il commit verificato rappresenta un altro punto di fragilità. Il badge verified di GitHub, presente sul commit d8c850c7, proviene da una firma GitHub ma non stabilisce che la modifica sia stata autorizzata dal maintainer. Come nota Snyk: "A verified badge proves that GitHub signed the commit object. It does not establish that the change was authorized by the project maintainer."
Questo crea un problema di interpretazione per gli strumenti di sicurezza e per gli sviluppatori: la presenza di firme e badge non equivale a validazione del contenuto o dell'autorizzazione.
C2 decentralizzato e persistenza tramite token watcher
L'infrastruttura di comando e controllo si basa su uno smart contract Ethereum StringListStore all'indirizzo 0xE1f2395ee43e45A1556EC6438a88c31B83493103. Wiz Research ha identificato query eth_call a questo contratto, inizialmente configurato con tre domini e poi aggiornato a npm-cache[.]com. La struttura è infrastructure-agnostic: gli aggressori possono modificare i domini C2 senza toccare il payload su disco.
Un meccanismo di persistenza particolarmente insidioso è il token revocation watcher (gh-token-monitor). Snyk ha confermato che questo componente osserva quando un token GitHub rubato viene revocato ed esegue un handler controllato dall'attaccante. La rotazione delle credenziali, normalmente considerata contromisura, diventa in questo caso trigger per azioni malevole aggiuntive.
Aikido Security ha contato oltre 434 pacchetti compromessi con oltre due miliardi di download mensili combinati.
Cosa fare adesso
Gli sviluppatori e le organizzazioni che hanno installato qualsiasi pacchetto della famiglia keyv il 4 agosto 2026 o clonato il repository devono considerare l'ambiente compromesso. Le azioni prioritarie derivano direttamente dall'analisi delle fonti.
Auditare i lockfile per identificare versioni sospette pubblicate nella finestra temporale dell'attacco, con attenzione alle 11 release malevole documentate da Snyk. Isolare gli host che hanno eseguito installazioni nel periodo critico e procedere alla rotazione delle credenziali da sistemi verificati puliti.
Monitorare esplicitamente i file di configurazione agent non coperti dagli scanner tradizionali, inclusi .claude/settings.json e .vscode/tasks.json, sia nei repository interni che nelle dipendenze estratte. Verificare la presenza di hook SessionStart e task con runOn folderOpen.
Rivedere i criteri di trust per le attestazioni SLSA e i badge verified: questi meccanismi attestano l'origine della build, non l'integrità del sorgente upstream o l'autorizzazione della modifica.
Un modello di attacco che ridefinisce i confini del possibile
L'incidente keyv non è un caso isolato ma la dimostrazione operativa di tecniche che erano state teorizzate. La combinazione di provenance firmata, file AI agent invisibili agli scanner, e C2 basato su smart contract Ethereum costituisce un modello riproducibile. La persistenza tramite token revocation watcher inverte la logica della risposta incidenti: una contromisura standard diventa vettore di ulteriore compromissione.
La scala di reach è significativa: keyv registra circa 127 milioni di download settimanali, flat-cache e file-entry-cache hanno ciascuno circa 565-580 milioni di download mensili. Aikido ha osservato circa 1.300 repository GitHub pubblici creati il 4 agosto per l'esfiltrazione. Wiz Research segnala un'espansione del target su credenziali del 70% rispetto a ondate precedenti.
Il dato più preoccupante resta la struttura del vettore: finché gli strumenti di sicurezza non leggeranno i file di configurazione degli agent AI con la stessa attenzione dedicata alle dipendenze, ogni apertura di progetto in un IDE sarà potenzialmente un'occasione di esecuzione. La provenance firmata, intesa come garanzia, può invece diventare un'inferenza falsa di sicurezza.
Domande frequenti
Perché la provenance SLSA non ha bloccato l'attacco?
Le attestazioni SLSA verificano che la build provenga da un workflow trusted e che l'artefatto non sia stato modificato dopo la firma. Non verificano che il sorgente su cui gira il workflow non sia stato compromesso. In questo caso, GitHub Actions ha firmato correttamente un artefatto costruito da codice malevolo.
I file AI agent sono una minaccia anche senza installazione npm?
Sì. I file .claude/settings.json e .vscode/tasks.json nel repository attivano esecuzione al folder open, indipendentemente dall'installazione del pacchetto. Questo li rende un vettore autonomo, non rilevato dagli scanner di dipendenze.
Qual è lo stato di remediation?
Al momento della ricerca Snyk non erano disponibili versioni pulite successor per keyv@6.0.0. Tre pacchetti erano stati rimossi da npm entro le 11:16 UTC del 4 agosto. Il maintainer jaredwray non ha fornito aggiornamenti pubblici sullo stato del proprio account.
Fonti
- https://www.techtimes.com/articles/323089/20260805/keyv-npm-supply-chain-attack-hides-malware-ai-agent-files-scanners-never-read.htm
- https://snyk.io/blog/inside-keyv-npm-compromise-preinstall-malware-trusted-provenance-ide-hooks/
- https://snyk.io/blog/node-gyp-supply-chain-compromise-self-propagating-npm-worm-binding-gyp/
- https://security.snyk.io/vuln/SNYK-JS-KEYV-18515941
- https://security.snyk.io/package/npm/cacheable
Le informazioni sono state verificate sulle fonti citate e aggiornate al momento della pubblicazione.