Keyv/Cacheable-npm-Kompromittierung: Mini-Shai-Hulud-Wurm vergiftet Hunderte Pakete über preinstall-Hook und Claude-Code-/VS-Code-Autostart
Am 4. August 2026 wurde die Release-Pipeline von keyv (619 Mio. Downloads/Monat laut Snyk) und rund einem Dutzend verwandter npm-Pakete aus dem cacheable-Umfeld kompromittiert. Ein neu eingefügter preinstall-Hook lädt eine verschlüsselte Bun-Runtime-Payload (Math_Symbol.js, ca. 728 KB), die Cloud- (AWS/GCP/Azure), CI/CD-, npm- und GitHub-Credentials erntet. Der Wurm verbreitet sich selbständig weiter, indem er gestohlene Publish-Tokens nutzt und dank npms Trusted-Publishing-Attestierung sogar kryptographisch „echt“ signierte bösartige Releases erzeugt. Zusätzlich legt er Autostart-Hooks in .claude/settings.json und .vscode/tasks.json ab — Code läuft dann schon beim Öffnen eines geklonten Repos in Claude Code oder VS Code, ganz ohne npm install. Snyk führt den Vorfall als SNYK-JS-KEYV-18515941 (Critical); eine offizielle CVE-Nummer war zum Zeitpunkt dieses Artikels noch nicht vergeben.
TL;DR — 90 Sekunden
- Betroffen?
Projekte mit einer direkten oder transitiven Abhängigkeit auf
keyv@6.0.0,cacheable@2.5.1,cacheable-request@13.0.20,flat-cache@6.1.24,file-entry-cache@11.1.6,cache-manager@7.2.10sowie mehrere@cacheable/*-Scoped-Pakete (u. a.net,node-cache,memory).flat-cache/file-entry-cacheerreichen viele Teams indirekt über ESLint.- Risiko?
Kritisch. Ein
preinstall-Hook führt beim bloßennpm installCode mit Entwickler-/CI-Rechten aus, lädt eine verschlüsselte Bun-Payload nach und erntet Cloud-, CI/CD- und Registry-Credentials. Zusätzlich pflanzt der Wurm Autostart-Hooks in.claude/settings.jsonund.vscode/tasks.json, die schon beim Öffnen eines geklonten Repos auslösen — auch ohne Installation.- Sofortmaßnahme?
Betroffene Pakete per
overrides/resolutionsauf letzte saubere Versionen fixieren, Lockfiles ohne Skriptausführung neu aufbauen (--ignore-scripts), auf die dokumentierten IOCs prüfen — bevor Tokens rotiert werden (der Wurm überwacht Token-Widerruf und triggert dabei zusätzliche Payloads).- Empfehlung?
Jedes Team mit Node.js-/npm-Build- oder CI-Pipeline sollte umgehend die eigene Dependency-Tree gegen die betroffenen Pakete prüfen — auch transitiv, auch wenn keine der Top-Level-Dependencies direkt betroffen aussieht.
- Kritikalität?
critical — aktiver, sich selbst verbreitender Lieferketten-Wurm mit Credential-Diebstahl, IDE-Persistenz und Anti-Forensik-Mechanismus gegen Token-Rotation.
Was ist das Problem?
Laut übereinstimmender Analyse von Snyk, Socket.dev, Cloudsmith, Wiz und weiteren Anbietern wurde am 4. August 2026 die Release-Pipeline von keyv — gepflegt vom Maintainer jaredwray — kompromittiert. Laut Snyks Rekonstruktion wurden gegen 09:02–09:17 UTC bösartige Commits ins keyv-Repository eingespielt, die einen preinstall-Skript-Hook ("preinstall": "node setup.mjs") sowie die zugehörigen Payload-Dateien hinzufügten. Um 09:35 UTC wurde keyv@6.0.0 mit diesem Hook auf npm veröffentlicht — inklusive gültiger npm-Provenance-Attestierung, da der Build-Prozess selbst unverändert und legitim über GitHub Actions lief. Genau das ist der zentrale Punkt: npm-Provenance bezeugt, dass ein bestimmter Workflow ein Artefakt gebaut hat — nicht, dass der Quellcode, der in diesen Workflow eingespeist wurde, vertrauenswürdig ist. War das Maintainer-Konto, der Repo-Zugriff oder die CI-Credentials vor der Veröffentlichung kompromittiert, signiert die Provenance ein bösartiges Artefakt genauso bereitwillig wie ein sauberes.
Der preinstall-Hook lädt einen rund 29,9 KB großen Loader (setup.mjs), der Plattform und Architektur erkennt, eine eigenständige Bun-Runtime herunterlädt und damit eine rund 728 KB große, polymorph Base91-kodierte zweite Stufe (Math_Symbol.js) ausführt — außerhalb der üblichen Node-basierten Monitoring-Pfade. Zwischen 10:09 und 10:14 UTC folgten die cacheable-Familie, danach weitere Pakete wie ecto@5.0.1 (10:28 UTC). Der Wurm verbreitet sich eigenständig: Er durchsucht nach weiteren Paketen des/der kompromittierten Maintainer, injiziert denselben preinstall-Hook, berechnet Integrity-/Shasum-Felder neu, erhöht die Versionsnummer und veröffentlicht über npms Trusted Publishing erneut — wodurch auch die Folge-Releases gültige Attestierungen erhalten.
Ein zweiter, vom Installationsschritt unabhängiger Auslösepfad macht den Vorfall besonders bemerkenswert: Das kompromittierte Repository enthält zusätzlich .claude/settings.json mit einem SessionStart-Hook sowie .vscode/tasks.json mit einer runOn: "folderOpen"-Task, die jeweils ein eigenes setup.mjs aufrufen. Wird ein betroffenes Repository lediglich in Claude Code oder VS Code geöffnet — ohne npm install, ohne Build —, läuft der Loader trotzdem. Damit reicht bei diesem Vorfall bereits das bloße Klonen und Öffnen eines Repos als Infektionsweg, nicht nur die Installation als Abhängigkeit.
Wer ist betroffen?
| Paket | Vergiftete Version | Letzte saubere Version |
|---|---|---|
keyv | 6.0.0 | 5.6.0 |
cacheable | 2.5.1 | 2.5.0 (letzte Version vor dem Vorfall prüfen) |
cacheable-request | 13.0.20 | 13.0.19 (letzte Version vor dem Vorfall prüfen) |
flat-cache | 6.1.24 | 6.1.23 |
file-entry-cache | 11.1.6 | 11.1.5 |
cache-manager | 7.2.10 | 7.2.9 |
@cacheable/net, @cacheable/node-cache, @cacheable/memory u. a. Scoped Packages | je nach Paket, siehe Snyk-Advisory SNYK-JS-KEYV-18515941 | letzte Version vor dem Vorfall |
Besonders relevant für TYPO3-/PHP-Teams: flat-cache und file-entry-cache erreichen viele Projekte nicht als direkte Abhängigkeit, sondern transitiv über ESLint im Frontend-Build (z. B. bei TYPO3-Sitepackages mit npm-basiertem Asset-Build). Ein npm ls ohne --all übersieht solche transitiven Treffer. Die genaue, vollständige Paketliste entwickelt sich mit der Untersuchung weiter — maßgeblich ist die jeweils aktuelle Fassung der Snyk-Advisory SNYK-JS-KEYV-18515941 sowie der Socket.dev- und Wiz-Analysen.
Auswirkungen
Der Payload zielt laut Snyk und Socket.dev breit auf Zugangsdaten: GitHub- und npm-Tokens, Cloud-Credentials (AWS-Metadatenüber IMDSv1/v2, GCP-Service-Account-Keys, Azure-Client-Secrets), HashiCorp-Vault-Tokens, Kubernetes-Service-Account-Tokens, SSH-Schlüssel, TLS-Zertifikate, Datenbank-Connection-Strings sowie den Speicher von GitHub-Actions-Runnern (inkl. OIDC-Tokens und Repository-Secrets). Exfiltriert wird u. a. über neu angelegte, öffentliche GitHub-Repositories sowie DNS-Tunneling.
Besonders heikel ist ein dokumentierter Persistenzmechanismus („gh-token-monitor“), der gestohlene GitHub-Tokens überwacht: Wird ein Token widerrufen, führt der Mechanismus einen vom Angreifer hinterlegten Handler aus — die übliche Reihenfolge „eingrenzen, dann Tokens rotieren“ wird damit gegen die eigene Incident Response gewendet. Wer Tokens rotiert, bevor die Persistenz entfernt ist, löst potenziell einen zusätzlichen, aktiv ausgelösten Schadcode-Pfad aus.
Da der Wurm sich selbständig über gestohlene Publish-Tokens weiterverbreitet und dabei gültige npm-Provenance-Attestierungen erhält, versagt an dieser Stelle ein rein auf Signaturprüfung gestütztes Vertrauensmodell: „kryptographisch signiert“ bedeutet hier ausdrücklich nicht „vertrauenswürdiger Quellcode“. Betroffen sind nicht nur Produktionsumgebungen, sondern auch Entwickler-Laptops und CI-Runner — überall dort, wo eines der Pakete installiert oder ein betroffenes Repository geöffnet wurde.
Mitigation / Sofortmaßnahmen
Operativer Entscheidungsblock
- Jetzt handeln, wenn … eines der betroffenen Pakete (direkt oder transitiv, z. B. via ESLint) in Ihrem Dependency-Tree auftaucht — Produktions- und Entwicklungs-/CI-Umgebungen.
- Mit Priorität prüfen, wenn … Repositories in den letzten Tagen geklont oder in Claude Code/VS Code geöffnet wurden, ohne dass ein Dependency-Scan lief.
- Beobachten, wenn … keines der Pakete im Tree auftaucht — die Paketliste entwickelt sich mit der laufenden Untersuchung weiter, ein erneuter Scan in den kommenden Tagen ist sinnvoll.
Schritt 1 — betroffene Pakete auf saubere Versionen fixieren
{
"overrides": {
"keyv": "5.6.0",
"cacheable": "2.5.0",
"cacheable-request": "13.0.19",
"flat-cache": "6.1.23",
"file-entry-cache": "11.1.5",
"cache-manager": "7.2.9"
}
}
// package.json (npm "overrides"); bei Yarn "resolutions" verwenden
Schritt 2 — Lockfile ohne Skriptausführung neu aufbauen
npm install --package-lock-only --ignore-scripts
rm -rf node_modules
npm cache clean --force
npm ci --ignore-scripts
Schritt 3 — Persistenz entfernen, bevor Tokens rotiert werden
# nach dem gh-token-monitor-Persistenzmechanismus suchen:
ls -la ~/.local/bin/ ~/.config/gh-token-monitor/ \
~/.config/systemd/user/ 2>/dev/null
ls -la ~/Library/LaunchAgents/ 2>/dev/null # macOS
# forensische Kopie anlegen, dann Persistenz entfernen
# (systemd-Unit stoppen/deaktivieren bzw. LaunchAgent entladen),
# erst danach mit Schritt 4 fortfahren
Schritt 4 — Credentials rotieren
# GitHub-Token: widerrufen und neu ausstellen
# npm-Token: widerrufen (npm token revoke) und neu ausstellen
# Cloud-Keys (AWS/GCP/Azure), Vault-Tokens, Kubernetes-Service-Account-Tokens,
# SSH-Keys und Datenbank-Connection-Strings ebenfalls rotieren,
# wenn eine betroffene Maschine/CI-Runner die Pakete installiert hatteDetection / Prüfung
Dependency-Tree prüfen (auch transitiv)
npm ls keyv flat-cache file-entry-cache cacheable-request \
cacheable cache-manager @cacheable/net @cacheable/node-cache \
@cacheable/memory --all
Nach bekannten Payload-Dateien und IOCs suchen
find "$HOME" /tmp -name setup.mjs -o -name Math_Symbol.js \
-o -name gh-token-monitor.sh -o -name gh-token-monitor.service \
-o -name com.user.gh-token-monitor.plist 2>/dev/null
# Prozesskette prüfen: node setup.mjs, das eine heruntergeladene
# bun-Binärdatei startet; temporäre Verzeichnisse nach dem Muster
# "bun-dl-*" suchen
find /tmp -maxdepth 2 -iname "bun-dl-*" 2>/dev/null
Kompromittierte preinstall-Hooks im node_modules-Baum aufspüren
find node_modules -name package.json -print0 | xargs -0 node -e '
const fs = require("node:fs");
for (const file of process.argv.slice(1)) {
try {
const pkg = JSON.parse(fs.readFileSync(file, "utf8"));
if (pkg.scripts?.preinstall === "node setup.mjs") {
console.log(`${pkg.name}@${pkg.version}`);
}
} catch {}
}
'
IDE-/Editor-Autostart-Hooks prüfen
# in jedem geklonten Repository prüfen, ob diese Dateien vorhanden
# sind und verdächtige setup.mjs-Aufrufe enthalten:
git -C /pfad/zum/repo show HEAD:.claude/settings.json 2>/dev/null
git -C /pfad/zum/repo show HEAD:.vscode/tasks.json 2>/dev/null | grep -A3 folderOpen
CI/CD- und Cloud-Audit-Logs prüfen
- npm-Account: unerwartete Veröffentlichungen am/nach dem 4. August 2026 prüfen (
npm profile get, Audit-Log im npm-Account-Dashboard). - GitHub: neu angelegte, unbekannte öffentliche Repositories im eigenen Account/Org prüfen (typisches Exfiltrationsziel dieses Wurms).
- Cloud-Provider: CloudTrail/Audit-Logs auf ungewöhnliche API-Aufrufe von Build-Agents/CI-Runnern in den letzten Tagen prüfen.
Betreiberempfehlung
Mid-Market
Dependency-Tree aller aktiven Node.js-/npm-Projekte (inkl. Frontend-Build-Toolchains wie TYPO3-Sitepackages mit ESLint) heute gegen die betroffene Paketliste prüfen. Lockfiles ohne Skriptausführung neu aufbauen, Persistenzmechanismus prüfen, dann erst Tokens rotieren.
Enterprise / Multi-Repo
Zentralen Scan über alle Repositories und CI-Pipelines fahren (SCA-Tooling oder das oben stehende npm ls --all-Kommando je Projekt), inklusive Entwickler-Laptops, auf denen betroffene Repos geklont/geöffnet wurden — nicht nur CI. Da der Wurm sich über legitime, attestierte Releases verbreitet, reicht eine reine Signaturprüfung nicht aus; Versionspins/Overrides sind Pflicht, bis die betroffene Paketliste als abschließend gilt.
Teams mit AI-Coding-Tools (Claude Code, Cursor, VS Code)
Jedes in den letzten Tagen geklonte oder geöffnete Repository gezielt auf .claude/settings.json und .vscode/tasks.json mit folderOpen-/SessionStart-Hooks prüfen — dieser Infektionsweg greift unabhängig davon, ob npm install überhaupt ausgeführt wurde.
Entscheidungsblock
Heute handeln, wenn: eines der betroffenen Pakete im Tree gefunden wurde oder ein Repo in den letzten Tagen geöffnet/geklont wurde. Diese Woche, wenn: Node.js-/npm-Toolchains im Einsatz sind, aber noch kein Scan lief. Beobachten, wenn: reine PHP-/TYPO3-Backends ohne npm-basierten Frontend-Build — hier bleibt Wachsamkeit sinnvoll, da sich die Paketliste noch entwickelt.
Was ich konkret getan habe
Ich behandle npm-Lieferketten-Würmer als Pipeline-Disziplin-Frage, nicht als Frage nach einem einzelnen bösen Paket. Für meine eigenen und betreuten Projekte mit npm-basiertem Frontend-Build (u. a. TYPO3-Sitepackages) habe ich den Dependency-Tree gegen die oben stehende Paketliste geprüft, --ignore-scripts als Standard für CI-Installationen verifiziert und die Renovate-Konfiguration so nachgezogen, dass betroffene Versionen explizit blockiert werden, bis die Advisory-Lage sich beruhigt hat. Zusätzlich habe ich stichprobenartig geprüft, ob in geklonten Repositories .claude/settings.json- oder .vscode/tasks.json-Dateien mit ungewöhnlichen Autostart-Hooks aufgetaucht sind — mit negativem Befund, aber genau diese Prüfung gehört aus meiner Sicht ab sofort zur Standard-Routine beim Öffnen fremder Repositories, nicht nur beim Installieren.
Häufige Fragen zum Keyv/Cacheable-npm-Wurm
Wie kann ein signiertes npm-Paket bösartig sein?+
npms Trusted-Publishing-Attestierung bezeugt, dass ein bestimmter GitHub-Actions-Workflow das veröffentlichte Artefakt gebaut hat — nicht, dass der Quellcode, der in diesen Workflow eingespeist wurde, vertrauenswürdig ist. War das Maintainer-Konto oder der Repo-Zugriff vor der Veröffentlichung kompromittiert, signiert die Provenance ein bösartiges Artefakt genauso bereitwillig wie ein sauberes.
Reicht npm install --ignore-scripts als Schutz?+
Gegen den preinstall-Hook-Pfad ja — --ignore-scripts verhindert, dass der Loader beim Installieren läuft. Gegen den zweiten Infektionsweg über .claude/settings.json und .vscode/tasks.json hilft das nicht: Der löst bereits beim Öffnen des Repos in Claude Code oder VS Code aus, unabhängig von npm install.
Warum zuerst Persistenz entfernen und erst dann Tokens rotieren?+
Weil ein dokumentierter Persistenzmechanismus („gh-token-monitor“) gestohlene GitHub-Tokens überwacht und bei Widerruf einen vom Angreifer hinterlegten Handler ausführt. Wird zuerst rotiert, kann das genau diesen zusätzlichen Schadcode-Pfad auslösen — die übliche Incident-Response-Reihenfolge wird hier gezielt gegen Verteidiger gewendet.
Ist das dasselbe wie der binding.gyp-Wurm vom Juni 2026?+
Nein, aber es gehört zur selben Familie selbst-verbreitender npm-Lieferketten-Würmer („Shai-Hulud“-Linie), über die wir hier bereits mehrfach berichtet haben — etwa den TanStack-Vorfall CVE-2026-45321 oder Miasma. Betroffene Pakete, Payload und Auslösepfade unterscheiden sich jeweils; die grundlegende Taktik (Lifecycle-Hook, Credential-Ernte, automatische Weiterverbreitung) ähnelt sich.
Betrifft mich das auch, wenn ich nur PHP/TYPO3 ohne npm einsetze?+
Direkt nicht, wenn Ihr Projekt keine npm-Abhängigkeiten hat. Sehr viele TYPO3-Sitepackages bauen ihre Frontend-Assets aber über npm-basierte Toolchains (Webpack, Vite, ESLint) — und genau dort landen flat-cache/file-entry-cache häufig transitiv über ESLint. Ein npm ls --all im Sitepackage-Verzeichnis schafft Klarheit.
Gibt es schon eine CVE-Nummer?+
Zum Zeitpunkt dieses Artikels nicht. Snyk führt den Vorfall unter der eigenen Advisory-ID SNYK-JS-KEYV-18515941 (eingestuft als Critical, CWE-506 — Embedded Malicious Code). Eine offizielle CVE-Zuweisung kann noch folgen; bis dahin ist die Snyk-Advisory die maßgebliche laufend aktualisierte Referenz.
Fazit
Der Keyv/Cacheable-Vorfall reiht sich in eine inzwischen lange Serie selbst-verbreitender npm-Würmer aus der „Shai-Hulud“-Familie ein — neu und bemerkenswert sind zwei Aspekte: Erstens nutzt der Wurm npms Trusted-Publishing-Attestierung aus, um seine eigenen bösartigen Releases kryptographisch „echt“ signieren zu lassen, was zeigt, dass Provenance-Prüfung allein kompromittierte Quellcode-Pipelines nicht erkennt. Zweitens erweitert er den Infektionsweg über die klassische npm install-Grenze hinaus in IDE-Autostart-Hooks (Claude Code, VS Code) — bloßes Öffnen eines geklonten Repos genügt. Wer Node.js-/npm-Toolchains einsetzt, sollte den eigenen Dependency-Tree prüfen, Lockfiles ohne Skriptausführung neu aufbauen und künftig auch Repository-lokale Editor-Konfigurationsdateien als Teil der Angriffsfläche behandeln — nicht nur package.json.
Quellen
- Snyk — Inside the keyv npm Supply Chain Compromise (SNYK-JS-KEYV-18515941)
- Socket.dev — Popular npm packages in the keyv and cacheable namespaces compromised
- Cloudsmith — Keyv and Cacheable npm Packages Compromised in Active Supply-Chain Attack
- Wiz — keyv and cacheable npm Package Hijacked in Supply Chain Attack
- The Hacker News — Keyv-Linked npm Worm Poisons Hundreds of Packages, Plants Claude Code and VS Code Hooks
- SafeDep — npm Worm Poisons 400+ Packages Across Nine Organisations
- Aikido — Keyv and friends compromised in npm supply chain attack
Ich prüfe, mitigiere und validiere Ihre npm-/CI-Lieferkette gegen Würmer wie den Keyv/Cacheable-Vorfall.
Dependency-Tree-Audit auf betroffene Pakete, Lockfile-Rebuild ohne Skriptausführung, Renovate-/CI-Härtung gegen kompromittierte Trusted-Publishing-Releases, Prüfung von Repository-lokalen Editor-Autostart-Hooks.
Plattform-Betrieb statt Beratung auf Papier: Ich prüfe, patche und härte Ihre Software-Lieferkette laufend.
Über den Autor

Kai Ole Hartwig
Programmiert seit 2002 – autodidaktisch gelernt, 2012 mit KO-Web selbständig gemacht. Über 100 Projekte, Fokus auf Security, Performance, Automatisierung und Qualität. Heute freiberuflich: DevSecOps-Beratung, Schulungen und Softwareentwicklung.