Am 4. August 2026 haben Angreifer das GitHub-Konto des Betreuers hinter keyv, eine Schlüssel-Wert-Speicherbibliothek mit rund 127 Millionen wöchentlichen npm-Downloads, und nutzte diesen Zugriff, um einen Wurm zum Diebstahl von Anmeldedaten in die gesamte Paketfamilie einzuschleusen. Derselbe Betreuer ist Eigentümer von zwischenspeicherbar (29 Millionen Downloads pro Monat), Flat-Cache (565 Millionen Downloads pro Monat), Dateieintrag-Cache (557 Millionen Downloads pro Monat) sowie mehrere andere weit verbreitete Caching-Programme, die alle von demselben Angriff betroffen waren.
Der Angriff erfolgte, indem schädliche Dateien direkt auf den Haupt Zweig und anschließend sofort die Erstellung einer neuen Version, was bedeutet, dass die manipulierten Versionen mit einer gültigen, von GitHub Actions signierten Herkunftsangabe auf npm veröffentlicht wurden.
Zu den betroffenen Paketen gehören:
keyv6,0,0 (604 Mio./Monat)Flat-Cache6,1,24 (580 Mio./Monat)Dateieintrag-Cache11,1,6 (571 Mio./Monat)zwischenspeicherbare Anfrage13.0.20 (137 Mio./Monat)zwischenspeicherbar2,5,1 (30 Mio./Monat)@cacheable/memory2,2,1 (28 Mio./Monat)Cache-Manager7,2,10 (16 Mio./Monat)@cacheable/node-cache3.1.2 (6 Mio./Monat)@cacheable/utils2,5,1 (34 Mio./Monat)@cacheable/net2.1.1 (3,7 K/Monat)ecto5,0,1 (4,5 K/Monat)
Wir beobachten zudem eine sehr aktive Ausbreitung dieses Supply-Chain-Wurms auf andere Betreuer und Pakete, darunter auch große Organisationen:
@deliveroo/reevent1.0.1@or-sdk/Einladungen1.4.9@picsart/ai-sdk3.32.2@qlik/embed-runtime1.6.4picasso.js2.11.6
Aktualisierung – 4. August 2026, 13:37 Uhr MESZ: Mindestens 434 Pakete (in 1.381 Versionen) wurden von dem Wurm kompromittiert; zum Zeitpunkt der Erstellung dieses Artikels belief sich die Gesamtzahl der monatlichen Installationen auf über 2 Milliarden .
Was geschah
Jedes Paket der Familie erhielt zwei neue Dateien, setup.mjs und Math_Symbol.js, zusammen mit einem "preinstall": "node setup.mjs" Eintrag zu jedem hinzugefügt package.json. Jeder, der mitgelaufen ist npm install gegen eine betroffene Version hätte setup.mjs automatisch ausgeführt werden, bevor ihre Installation abgeschlossen ist.
setup.mjs ist ein stark verschleierter Dropper. Seine einzige Aufgabe besteht darin, die Bun-JavaScript-Laufzeitumgebung unbemerkt von github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/ herunterzuladen und damit die eigentliche Payload auszuführen, Math_Symbol.js:
execFileSync(<bun binary>, ['<script_dir>/Math_Symbol.js'], {
stdio: 'inherit',
cwd: <script_dir>
})Der Math_Symbol.js ist eine stark verschleierte JavaScript-Datei mit einer Größe von 728 KB, die Anmeldedaten-Stealer enthält, welche secrets der Umgebung des Opfers sammeln, diese verschlüsseln und in ein öffentliches GitHub-Repository exfiltrieren, dessen Beschreibung lautet: „Shai-Hulud: Und schon geht’s wieder los". Die Nutzlast enthält zudem eine wurmartige Verbreitungsfunktion, um Pakete anderer Betreuer zu infizieren, die eines der kompromittierten Pakete installiert haben.
Was es stiehlt
Der Math_Symbol.js Die Datei implementiert eine Reihe von Extraktoren für Anmeldedaten, die jeweils auf einen anderen Speicherort für geheime Daten auf dem Rechner des Opfers abzielen.
npm-Tokens
Liest ~/.npmrc und durchsucht das Dateisystem nach weiteren .npmrc Dateien. Auszüge authToken Werte und etwaige //registry.*:_authToken=... Einträge. Überprüft jedes Token in Echtzeit anhand von registry.npmjs[.]org/-/whoami vor der Exfiltration.
GitHub-Tokens
Es werden drei Token-Formate abgedeckt: klassische PATs (ghp_...) und OAuth-Token (gho_...), Server-zu-Server-Token der GitHub-App (ghs_...) sowie JWT-OIDC-Token. Zu den Quellen gehören ~/.config/gh/hosts.yml, Umgebungsvariablen und einen Dateisystem-Scan.
Auf GitHub-Actions-Runner führt die Nutzlast zudem einen Shell-Befehl aus, der den Arbeitsspeicher des Runner-Prozesses direkt ausliest, um den gesamten Secret-Speicher auszulesen. Dabei wird ACTIONS_ID_TOKEN_REQUEST_TOKEN und ACTIONS_ID_TOKEN_REQUEST_URL um OIDC-Token zu stehlen, die für die Veröffentlichung über npm verwendet werden.
AWS-Anmeldeinformationen
~/.aws/credentialsund~/.aws/config, wobei alle benannten Profile analysiert werdenAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY, undAWS_SESSION_TOKENUmgebungsvariablen- EC2-Instanz-Metadatendienst unter
169.254.169.254, wobei zunächst IMDSv2 ausprobiert wird, mit einem Fallback auf IMDSv1 - ECS-Endpunkt für container unter
169.254.170.2 - AWS Secrets , Anruf
secretsmanager:ListSecretsüber mehrere Regionen hinweg, um alle dort secrets zu erfassen und zu entwenden
Kubernetes secrets
Liest das Dienstkontotoken, das CA-Zertifikat und den Namespace aus secrets.io/serviceaccount/. Nutzt das Token des Dienstkontos, um die Kubernetes-API direkt abzufragen und alle secrets Namespace abzurufen. Zielt außerdem auf KUBECONFIG und ~/.kube/config.
HashiCorp Vault Tokens
Überprüft sechs Quellen in der Reihenfolge ihrer Priorität: die VAULT_TOKEN Umgebungsvariable, ~/.vault-token, der Pfad zum GitHub-Actions-Runner /home/runner/.vault-token, mehrere bekannte container , eine Kubernetes-Authentifizierung unter Verwendung des gestohlenen JWT des Dienstkontos sowie den AWS-IAM-Authentifizierungsendpunkt von Vault unter Verwendung beliebiger gestohlener AWS-Anmeldedaten. Nach dem Erhalt eines Tokens listet es alle KV-Speicher über /v1/sys/mounts und liest alle Geheimnisse aus den KV-Pfaden v1 und v2 aus.
Stripe- und Slack-Token
Sucht nach Stripe-API-Schlüsseln (sowohl Test- als auch Live-Schlüssel, sk_ und pk_ Präfixe) und Slack-Token (xox[baprs]-...) in allen Dateien, die vom Dateisystem-Scanner erfasst wurden.
Allgemeiner Dateisystem-Scan
Ein plattformabhängiger Scanner (macOS vs. Linux) führt etwa 200 Glob-Muster im Dateisystem aus und zielt dabei unter anderem auf Folgendes ab:
.env,.env.*, und.envrcDateien- Dateien mit privaten Schlüsseln (
*.pem,*.key,*.S. 12,*.pfx,*.jks) - SSH-Schlüssel und Konfiguration (
id_rsa,id_ed25519,.ssh/config) - Terraform-State-Dateien und
.tfvars - Anmeldedateien für Docker-Registerstellen (
docker/config.json) - KeePass-Datenbanken (
*.kdbx) - VPN-Konfigurationen (
*.ovpn) - IDE-Konfigurationsdateien, darunter
.vscode/tasks.jsonund.claude/settings.json
Dateien, die größer als 5 MB sind, werden übersprungen. Es werden bis zu 64 gleichzeitige Lesevorgänge durchgeführt. Außerdem wird auf alle gescannten Dateien eine generische Regex-Engine angewendet, die PEM-Privatschlüssel, öffentliche SSH-Schlüssel, Azure-Speicherschlüssel, Datenbankverbindungszeichenfolgen mit eingebetteten Anmeldedaten sowie generische Schlüssel=Wert Muster, die mit gängigen Feldnamen für geheime Daten übereinstimmen.
Exfiltration
Sobald die Anmeldedaten erfasst wurden, verschlüsselt die Payload das gesamte Bundle, bevor es an einen beliebigen Ort gesendet wird. Nur der Angreifer, der über den entsprechenden privaten Schlüssel von RSA verfügt, kann die hochgeladenen Daten entschlüsseln. Das bedeutet, dass die gestohlenen Daten zwar offen in der öffentlichen Infrastruktur vorliegen, für alle anderen jedoch unlesbar sind.
Das primäre Ziel für die Exfiltration ist ein öffentliches GitHub-Repository, dessen Beschreibung die Zeichenfolge„Shai-Hulud: Here We Go Again“ enthält. Zum Zeitpunkt der Erstellung dieses Artikels gibt es auf GitHub etwa 1.300 öffentliche Repositories, die dieser Zeichenfolge entsprechen und jeweils als Ablageort für das verschlüsselte Anmeldedatenbündel eines Opfers dienen.

Sollte der Upload auf GitHub fehlschlagen, wird die Nutzlast auf https://npm-cache[.]com:443/router, eine am 22.05.2026 registrierte Domain, die offenbar keinem legitimen Zweck dient. Diese Domain wird dynamisch aus einem Ethereum-Smart-Contract unter 0xE1f2395ee43e45A1556EC6438a88c31B83493103, wodurch der Angreifer die Infrastruktur jederzeit austauschen kann, ohne die Nutzlast zu verändern.
Selbstreplizierender Wurm
Die Payload stiehlt nicht nur Anmeldedaten, sondern nutzt diese auch aktiv, um die Malware auf andere Betreuer und Repositorys zu verbreiten. Sie verfügt über zwei unterschiedliche Infektionswege.
Infektion durch einen npm-Tarball
Unter Verwendung des gestohlenen npm-Tokens ruft die Payload Folgendes auf: https://registry.npmjs[.]org/-/npm/v1/tokens um alle Pakete aufzulisten, für die dieses Token Veröffentlichungsrechte besitzt, und anschließend für jedes einzelne den aktuellen Tarball abzurufen und zu entpacken. Vor der erneuten Veröffentlichung nimmt es die folgenden Änderungen vor:
- Erhöht die Patch-Version um eins (z. B.
1.2.3wird zu1.2.4) - Fügt hinzu
"preinstall": "node setup.mjs"zu den Paketskripten - Injektionen
setup.mjsundmath_init.js(funktional identisch mitMath_Symbol.js) in das Paket
Anschließend wird das geänderte Tarball-Archiv neu gepackt und in der Registry veröffentlicht.
Auf diese Weise verbreitet sich der Wurm über den ursprünglichen Betreuer hinaus. Nach der anfänglichen Kompromittierung des keyv Als Betreuer haben wir beobachtet, dass über 400 Pakete durch eine Ausbreitung innerhalb der Community infiziert wurden. Diese Infektionen der zweiten Generation lassen sich anhand der Verwendung von math_init.js anstatt Math_Symbol.js, da sie durch den „npm-Tarball-Injection“-Wurm infiziert wurden.
Infektion eines GitHub-Repositorys
Wenn die Nutzlast ein ghs_ Token: Es führt Commits in jedem Zweig durch, den es erreichen kann – bis zu 50 Zweige pro Repository –, wobei es zuerst die zuletzt aktiven Zweige durchläuft und dependabot und Copilot Zweige. Es fügt bösartige Hooks zu .claude/settings.json und .vscode/tasks.json damit die Payload automatisch ausgeführt wird, sobald ein Entwickler das Repository in VS Code öffnet oder darin eine Claude-Code-Sitzung startet – ohne dass ein „npm install“ erforderlich ist. Die Commits sind wie folgt verfasst: claude per E-Mail claude@users.noreply.github[.]com und die Botschaft weitergeben Chore: Konfiguration aktualisieren, die sich unter die echten Commits mischen.
Wie Aikido dies erkennt
Wenn Sie ein Aikido-Benutzer sind, überprüfen Sie Ihren zentralen Feed und filtern Sie nach Malware-Problemen. Dies wird als kritisches Problem mit 100/100 angezeigt. Aikido führt nächtliche Rescans durch, aber wir empfehlen, jetzt einen manuellen Rescan auszulösen.
Wenn Sie noch kein Aikido-Benutzer sind, können Sie ein Konto erstellen und Ihre Repos verbinden. Unsere Malware-Abdeckung ist im kostenlosen Plan enthalten, keine Kreditkarte erforderlich.
Für eine umfassendere Abdeckung Ihres gesamten Teams bietet Aikido's Device Protection Ihnen Transparenz und Kontrolle über die Softwarepakete, die auf den Geräten Ihres Teams installiert sind. Es deckt Browser Extensions, Code Libraries, IDE Plugins und Build Dependencies ab, alles an einem Ort. Stoppen Sie Malware, bevor sie installiert wird.
Für zukünftigen Schutz sollten Sie Aikido Safe Chain (Open Source) in Betracht ziehen. Safe Chain integriert sich in Ihren bestehenden Workflow, indem es npm-, npx-, yarn-, pnpm- und pnpx-Befehle abfängt und Pakete vor der Installation gegen Aikido Intel prüft.
Indikatoren für eine Kompromittierung (IOCs)
Dateien
setup.mjs- SHA-256
54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668
- SHA-256
setup.mjs(Version mit Übertragung innerhalb der Gemeinschaft)- SHA-256
fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1eb
- SHA-256
Math_Symbol.jsundmath_init.js- SHA-256
9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc
- SHA-256
Netzwerk
https://npm-cache[.]com:443/router— Endpunkt der Datenexfiltrationeth-mainnet.nodereal[.]ioAnfrage mit folgendem Inhalt:0xE1f2395ee43e45A1556EC6438a88c31B83493103
Andere
- Jedes öffentliche GitHub-Repository, dessen Beschreibung Folgendes enthält:
„Shai-Hulud: Schon wieder das Gleiche“— dies sind die vom Angreifer kontrollierten Repos, die zur Exfiltration von Anmeldedaten genutzt werden.

