Aikido

Keyv und Freunde wurden bei einem aktiven Shai-Hulud-Angriff auf die Lieferkette kompromittiert

Verfasst von
Ilyas Makari

Am 4. August 2026 kompromittierten Angreifer das GitHub-Konto des Maintainers hinter keyv, eine Key-Value-Speicherbibliothek mit rund 127 Millionen wöchentlichen npm-Downloads, und nutzte diesen Zugriff, um einen zugangsdatenstehlenden Worm in der gesamten Paketfamilie zu platzieren. Derselbe Maintainer besitzt cacheable (29 Mio. Downloads/Monat), flat-cache (565 Mio. Downloads/Monat), file-entry-cache (557 Mio. Downloads/Monat) und diverse andere weit verbreitete Caching-Utilities, die alle von demselben Angriff betroffen waren.

Die Kompromittierung erfolgte durch das direkte Hochladen schädlicher Dateien in das Haupt -Branch und die anschließende sofortige Freigabe eines neuen Releases, wodurch die vergifteten Versionen mit einer gültigen Provenienz, signiert von GitHub Actions, auf npm veröffentlicht wurden.

Zu den kompromittierten Paketen gehören:

  • keyv 6.0.0 (604 Mio./Monat)
  • flat-cache 6.1.24 (580 Mio./Monat)
  • file-entry-cache 11.1.6 (571 Mio./Monat)
  • cacheable-request 13.0.20 (137 Mio./Monat)
  • cacheable 2.5.1 (30 Mio./Monat)
  • @cacheable/memory 2.2.1 (28 Mio./Monat)
  • cache-manager 7.2.10 (16 Mio./Monat)
  • @cacheable/node-cache 3.1.2 (6 Mio./Monat)
  • @cacheable/utils 2.5.1 (34 Mio./Monat)
  • @cacheable/net 2.1.1 (3,7 Tsd./Monat)
  • ecto 5.0.1 (4,5 Tsd./Monat)

Wir beobachten zudem eine sehr aktive Verbreitung dieses Supply-Chain-Worms innerhalb der Community auf andere Maintainer und Pakete, darunter auch große Organisationen:

  • @deliveroo/reevent 1.0.1
  • @or-sdk/invitations 1.4.9
  • @picsart/ai-sdk 3.32.2
  • @qlik/embed-runtime 1.6.4
  • picasso.js 2.11.6

Update – 5. August 2026, 13:15 Uhr MESZ: Mindestens 444 Pakete (verteilt auf 1381 Versionen) wurden durch den Worm kompromittiert, mit insgesamt über 2 Milliarden monatlichen Installationen zum Zeitpunkt dieses Berichts.

Was geschah

Jedes Package in der Familie erhielt zwei neue Dateien, setup.mjs und Math_Symbol.jszusammen mit einem "preinstall": "node setup.mjs" Eintrag, der jeweils zu package.jsonhinzugefügt wurde. Jeder, der npm install gegen eine betroffene Version ausgeführt hat, hätte setup.mjs wird automatisch ausgeführt, bevor die Installation abgeschlossen ist.

setup.mjs ist ein stark verschleierter Dropper. Seine einzige Aufgabe besteht darin, unbemerkt die Bun JavaScript-Laufzeit von github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/ herunterzuladen und damit die echte Nutzlast 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 728 KB große JavaScript-Datei, die Datendiebe enthält, welche Secrets aus der Umgebung des Opfers abgreifen, die Funde verschlüsseln und an ein öffentliches GitHub-Repository exfiltrieren, dessen Beschreibung lautet:Shai-Hulud: Here We Go Again". Die Nutzlast enthält zudem eine wurmartige Verbreitungsfunktion, um Pakete anderer Maintainer zu infizieren, die eines der kompromittierten Pakete installiert haben.

Was es stiehlt

Der Math_Symbol.js Datei implementiert eine Reihe von Anmeldeinformationen-Extraktoren, die jeweils auf einen anderen Secret Store auf dem Zielsystem abzielen.

npm-Tokens

Liest ~/.npmrc und durchsucht das Dateisystem nach anderen .npmrc Dateien. Extrahiert authToken Werte und sämtliche //registry.*:_authToken=... Einträge. Validiert jedes Token live gegen registry.npmjs[.]org/-/whoami vor der Exfiltration.

GitHub-Tokens

Es wird auf drei Token-Formate abgezielt: klassische PATs (ghp_...) und OAuth-Token (gho_...), GitHub App Server-zu-Server-Token (ghs_...) sowie JWT-OIDC-Token. Quellen umfassen ~/.config/gh/hosts.yml, Umgebungsvariablen und einen Dateisystemscan.

Auf GitHub Actions Runnern führt die Nutzlast außerdem einen Shell-Befehl aus, der den Prozess Arbeitsspeicher des Runners direkt liest, um den gesamten Secrets-Speicher zu sichern. Es liest ACTIONS_ID_TOKEN_REQUEST_TOKEN und ACTIONS_ID_TOKEN_REQUEST_URL , um OIDC-Token zu stehlen, die für die npm-Veröffentlichung verwendet werden.

AWS-Anmeldeinformationen

  • ~/.aws/credentials und ~/.aws/config, wobei alle benannten Profile geparst werden
  • AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, und AWS_SESSION_TOKEN Umgebungsvariablen
  • EC2 Instance Metadata Service unter 169.254.169.254, wobei zuerst IMDSv2 mit einem Fallback auf IMDSv1 versucht wird
  • ECS Container-Metadatendateiendpunkt unter 169.254.170.2
  • AWS Secrets Manager, durch Aufruf von secretsmanager:ListSecrets über mehrere Regionen hinweg, um alle dort gespeicherten Secrets zu ermitteln und zu exfiltrieren

Kubernetes-Secrets

Liest das Dienstkontotoken, das CA-Zertifikat und den Namespace von /var/run/secrets/kubernetes.io/serviceaccount/. Nutzt das Service-Account-Token, um die Kubernetes-API direkt abzufragen und alle Secrets im Namespace abzurufen. Zielt zudem auf KUBECONFIG und ~/.kube/config.

HashiCorp Vault Tokens

Prüft sechs Quellen in folgender Prioritätenreihenfolge: die VAULT_TOKEN Umgebungsvariable, ~/.vault-token, den GitHub Actions Runner-Pfad /home/runner/.vault-token, mehrere bekannte Container-Pfade, einen Kubernetes-Auth-Login mit dem entwendeten Service-Account-JWT sowie den AWS-IAM-Auth-Endpunkt von Vault unter Verwendung eventuell entwendeter AWS-Zugangsdaten. Nach Erhalt eines Tokens werden alle KV-Stores über /v1/sys/mounts aufgelistet und sämtliche Secrets aus den KV-v1- und v2-Pfaden ausgelesen.

Stripe- und Slack-Tokens

Durchsucht alle vom Dateisystem-Scanner erfassten Dateien nach Stripe-API-Schlüsseln (sowohl Test- als auch Live- sk_ und pk_ Präfixe) und Slack-Tokens (xox[baprs]-...).

Allgemeiner Dateisystem-Scan

Ein plattformbewusster Scanner (macOS vs. Linux) führt rund 200 Glob-Patterns auf dem Dateisystem aus und zielt unter anderem auf:

  • .env, .env.*, und .envrc Dateien
  • Private Schlüsseldateien (*.pem, *.key, *.p12, *.pfx, *.jks)
  • SSH-Schlüssel und -Konfig (id_rsa, id_ed25519, .ssh/config)
  • Terraform-State-Dateien und .tfvars
  • Docker-Registry-Zugangsdateien (docker/config.json)
  • KeePass-Datenbanken (*.kdbx)
  • VPN-Konfigurationen (*.ovpn)
  • IDE-Konfigurationsdateien einschließlich .vscode/tasks.json und .claude/settings.json

Dateien über 5 MB werden übersprungen. Es werden bis zu 64 gleichzeitige Lesevorgänge verwendet. Zudem wird eine generische Regex-Engine über alle gescannten Dateien angewendet, die PEM-Private-Keys, öffentliche SSH-Schlüssel, Azure-Speicherschlüssel, Datenbank-Verbindungsstrings mit eingebetteten Anmeldeinformationen sowie generische key=value Muster markiert, die gängigen Secret-Feldnamen entsprechen.

Exfiltration

Sobald Zugangsdaten erfasst sind, verschlüsselt das Payload das gesamte Paket, bevor es an einen beliebigen Ort gesendet wird. Nur der Angreifer, der im Besitz des dazugehörigen RSA-Private-Keys ist, kann die hochgeladenen Daten entschlüsseln. Das bedeutet, dass die gestohlenen Daten offen auf öffentlicher Infrastruktur liegen, aber für alle anderen unlesbar sind.

Das primäre Exfiltrationsziel ist ein öffentliches GitHub-Repository, dessen Beschreibung die Zeichenfolge „Shai-Hulud: Here We Go Again“ enthält. Zum Zeitpunkt des Schreibens enthält GitHub rund 1.300 öffentliche Repositories, die dieser Zeichenfolge entsprechen und jeweils als Ablagepunkt für das verschlüsselte Anmeldedatenpaket eines Opfers dienen.

Schlägt der Upload bei GitHub fehl, greift das Payload als Fallback auf https://npm-cache[.]com:443/router, eine am 22.05.2026 registrierte Domain, die anscheinend keinen legitimen Zweck erfüllt. Diese Domain wird dynamisch von einem Ethereum-Smart-Contract abgerufen unter 0xE1f2395ee43e45A1556EC6438a88c31B83493103, wodurch der Angreifer die Infrastruktur jederzeit austauschen kann, ohne das Payload zu berühren.

Selbstreplizierender Wurm

Das Payload stiehlt nicht nur Anmeldedaten, sondern nutzt diese auch aktiv, um die Malware an andere Maintainer und Repositories zu verbreiten. Es verfügt über zwei unterschiedliche Infektionsvektoren.

npm-Tarball-Infektion

Unter Verwendung des gestohlenen npm-Tokens ruft das Payload Folgendes auf: https://registry.npmjs[.]org/-/npm/v1/tokens um jedes Paket aufzulisten, für das dieses Token Veröffentlichungsrechte besitzt, und ruft dann das aktuelle Tarball für jedes einzelne ab und entpackt es. Vor der erneuten Veröffentlichung nimmt es die folgenden Änderungen vor:

  • Erhöht die Patch-Version um eins (z. B. 1.2.3 wird zu 1.2.4)
  • Fügt "preinstall": "node setup.mjs" zu den Paketskripten hinzu
  • Injiziert setup.mjs und math_init.js (funktional identisch mit Math_Symbol.js) in das Paket

Es packt das modifizierte Tarball daraufhin wieder zusammen und veröffentlicht es in der Registry.

So verbreitet sich der Wurm über den ursprünglichen Maintainer hinaus. Nach der anfänglichen Kompromittierung des keyv Maintainers haben wir beobachtet, dass über 400 Pakete durch die Verbreitung in der Community infiziert wurden. Diese Infektionen der zweiten Generation sind an der Verwendung von math_init.js anstatt Math_Symbol.jserkennbar, da sie durch den npm-Tarball-Injektionswurm gestreut wurden.

GitHub-Repo-Infektion

Wenn die Nutzlast ein ghs_ Token findet, committet sie in jeden erreichbaren Branch (bis zu 50 Branches pro Repo), wobei sie bei den kürzlich am aktivsten genutzten Branches beginnt und dependabot und copilot Branches überspringt. Sie fügt bösartige Hooks zu .claude/settings.json und .vscode/tasks.json hinzu, sodass die Nutzlast beim nächsten Mal automatisch ausgeführt wird, wenn Entwickelnde das Repository in VS Code öffnen oder darin eine Claude Code-Session starten, ganz ohne npm install. Die Commits werden verfasst als claude mit der E-Mail-Adresse claude@users.noreply.github[.]com und tragen die Nachricht chore: update config, wodurch sie sich unauffällig unter echte 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.

Indicators of Compromise (IOCs)

Dateien

  • setup.mjs​
    • SHA-256 54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668
  • setup.mjs (Community-Verbreitungsversion)
    • SHA-256 fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1eb
  • Math_Symbol.js und math_init.js​
    • SHA-256 9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc

Netzwerk

  • https://npm-cache[.]com:443/router — Exfiltrationsendpunkt
  • eth-mainnet.nodereal[.]io Anfrage mit 0xE1f2395ee43e45A1556EC6438a88c31B83493103

Andere

  • Jedes öffentliche GitHub-Repository, dessen Beschreibung Folgendes enthält: "Shai-Hulud: Here We Go Again" — Dies sind die vom Angreifer kontrollierten Repositories, die für die Exfiltration von Zugangsdaten genutzt werden.

​

Teilen:

https://www.aikido.dev/blog/keyv-and-friends-compromised-in-npm-supply-chain-attack

Nach Malware scannen

Kostenlos starten
4.7/5
Falschpositive Ergebnisse leid?

Probieren Sie Aikido, wie 100.000 andere.
Jetzt starten
Erhalten Sie eine personalisierte Führung

Von über 100.000 Teams vertraut

Jetzt buchen
Scannen Sie Ihre App nach IDORs und realen Angriffspfaden

Von über 100.000 Teams vertraut

Scan starten
Erfahren Sie, wie KI-Penetrationstests Ihre App testen

Von über 100.000 Teams vertraut

Testen starten

Werden Sie noch heute sicher,
schnell und kostenlos.

Sichern Sie Code, Cloud und Laufzeit in einem zentralen System.
Verbinden Sie ein Repository, um herauszufinden, was die Reasoning Agents in Ihrer Codebasis finden.

Keine Kreditkarte erforderlich | Scan-Ergebnisse in 32 Sekunden.
Von über 150.000 Unternehmen vertraut