Ausgangspunkt der bestätigten Angriffskette war keyv@6.0.0. Diese Version ergänzte laut Quelltext den Befehl „node setup.mjs“ als preinstall-Kommando und brachte die Dateien setup.mjs und Math_Symbol.js mit, während der kompilierte Bibliothekscode unverändert blieb. In einer ersten Phase prüft der Schadcode auf Bun, lädt bei Bedarf Version 1.3.13 aus den offiziellen GitHub-Releases der Laufzeitumgebung herunter und übergibt dann an ein 727.680 Byte großes kompiliertes Bündel.

Die Payload kann nach der Analyse von SafeDep Material aus GitHub, npm, Cloud-Diensten, Vault, Kubernetes, Datenbanken und privaten Schlüsseln abgreifen. Hinzu kommt das Auslesen des Speichers von GitHub-Actions-Runnern, die Installation eines Watchers zur Token-Sperrung und eine npm-Veröffentlichungsfunktion. Socket hat zudem separat Code entschlüsselt, der Pakete verändert, versioniert und mit einer gestohlenen npm-Identität erneut veröffentlicht.

Socket warnt, dass jede Workstation oder jeder Runner, der eine betroffene Version ausgeführt hat, als durchgesickert bei Zugangsdaten behandelt werden sollte. SafeDep rät Incident-Teams, zunächst den Watcher zur Überwachung von Credential-Sperrungen zu entfernen und erst danach offengelegte Token und Schlüssel zu rotieren. Der Grund: Die Sperrung selbst ist laut den Forschern der Auslöser; wer zuerst rotiert, kann einen vom Angreifer hinterlegten lokalen Handler starten. npm 12 blockiert nicht genehmigte Lifecycle-Skripte von Abhängigkeiten standardmäßig, ältere npm-Clients und andere Installationspfade mit erlaubten Lifecycle-Skripten bleiben aber anfällig.

Einen festen, kampagnenweiten Überblick über alle weiterhin als „latest“ markierten Pakete gab es laut Bericht nicht, weil sich der Registry-Stand zu schnell änderte. SafeDep beobachtete, dass npm-Paketseiten für mindestens neun Pakete aus dem ursprünglichen Set wieder frühere Releases als aktuelle Version auswiesen, darunter keyv@5.6.0, flat-cache@6.1.23 und cache-manager@7.2.9. Deshalb sollen Prüfungen auf konkrete Paketnamen, tatsächlich aufgelöste Versionen und Lockfiles gestützt werden, nicht auf zwischengespeicherte Listen aktueller Tags.

Hinzu kommt ein zweiter Ausführungspfad im Repository. In .claude/settings.json liegt ein SessionStart-Hook, der .vscode/setup.mjs aufruft. Die Datei .vscode/tasks.json enthält eine Aufgabe „Environment Setup“ mit runOn: folderOpen, die .claude/setup.mjs startet. Diese Dateien schaffen einen Weg, den Schadcode aus einem ausgecheckten Repository heraus zu starten, laufen aber nicht in jeder Standardumgebung bedingungslos. VS Code blockiert automatische Tasks in einem nicht vertrauenswürdigen Workspace und fragt standardmäßig nach Erlaubnis; Claude Code wendet Workspace-Vertrauen auf projektspezifische Repository-Einstellungen an.

Auffällig ist, dass die kompromittierte Keyv-Veröffentlichung gültige OIDC- und SLSA-Provenance trug, weil sie durch den legitimen GitHub-Actions-Release-Workflow des Projekts lief. Laut Bericht bestätigte diese Attestierung den Build-Prozess korrekt, konnte aber nicht belegen, dass die Eingangsbasis des Builds unbedenklich war. Auch der Commit, der die Claude-Code- und VS-Code-Hooks einpflanzte, trug ein grünes, von GitHub verifiziertes Abzeichen und nannte github-actions[bot] als Autor. SafeDep betont, dass weder das verifizierte Abzeichen noch das Autorenfeld erkennen lassen, wer die Zugangsdaten kontrollierte, mit denen der Commit eingereicht wurde.

Nicht alle Pakete im Umfeld des ursprünglichen Maintainers waren betroffen. SafeDep zufolge blieben die veröffentlichten @keyv/*-Adapter und die Keyv-5.x-Linie sauber. Das Repository selbst bleibt jedoch ein separates Risiko: Ein späterer Commit verteilte die Payload-Dateien auf alle 19 Workspace-Pakete, sodass ein Release aus dem weiterhin kompromittierten Baum diese Dateien wieder enthalten würde.

In einem Update erhöhte SafeDep den registry-gestützten Zähler auf 1.684 manipulierte Versionen unter 420 Paketnamen, die neun Organisationen zugeordnet sind. Das Unternehmen erklärte, der Wurm habe sich alle zwei bis sieben Minuten zwischen Organisationen bewegt und den organisationsübergreifenden Veröffentlichungsstoß in ungefähr einer halben Stunde abgeschlossen. Aikidos gesonderte Zählung liegt bei Paketnamen höher, bei Versionen aber niedriger; beide Werte sollen deshalb nicht zusammengezählt werden. Zusätzlich zählten die Forscher 546 öffentliche GitHub-Repositories, die am 4. August mit der Beschreibung „Shai-Hulud: Jetzt geht es wieder los“ und einem Verzeichnis results/ erstellt wurden. Diese Repositories gelten als mögliche Exfiltrations- oder Staging-Artefakte, nicht als 546 bestätigte Opfer. Semgrep dokumentierte dieselben Claude-Code- und VS-Code-Hooks, den Dateinamen setup.mjs und den Download von Bun 1.3.13 bereits bei einer Kompromittierung des PyPI-Pakets lightning im April. Aikido ordnet die August-Aktivität der Familie Shai-Hulud zu. Laut Bericht belegt diese Überschneidung eine Verbindung auf Malware-Familienebene, aber weder der Erstzugang noch ein benannter Akteur sind bekannt.