Axios auf npm kompromittiert, Remote-Access-Trojaner verteilt
(stepsecurity.io)- Zwei bösartige Versionen des weit verbreiteten axios-HTTP-Clients wurden auf npm veröffentlicht und verteilten bei der Installation einen Remote-Access-Trojaner (RAT)
- Die Angreifer umgingen GitHub Actions durch Diebstahl der Zugangsdaten eines Maintainer-Kontos und luden die bösartigen Pakete manuell hoch
- Die bösartigen Versionen enthielten die gefälschte Abhängigkeit
plain-crypto-js@4.2.1, die perpostinstall-Skript den RAT installierte und Spuren entfernte - Der RAT infiziert macOS, Windows und Linux und kommuniziert mit dem C2-Server (
sfrclak.com:8000), um weitere Payloads herunterzuladen - npm und GitHub entfernten die bösartigen Versionen schnell, doch die Bedeutung stärkerer Supply-Chain-Sicherheit und des Schutzes von Zugangsdaten wurde erneut deutlich
Überblick über den axios-Angriff auf die npm-Supply-Chain
- Am 31. März 2026 wurden zwei bösartige Versionen der weit verbreiteten axios-HTTP-Client-Bibliothek (
axios@1.14.1,axios@0.30.4) auf npm veröffentlicht - Die Angreifer stahlen die npm-Zugangsdaten eines zentralen axios-Maintainers, um die GitHub-Actions-CI/CD-Pipeline zu umgehen und die bösartigen Pakete manuell zu veröffentlichen
- Beide Versionen schleusten eine gefälschte Abhängigkeit namens
plain-crypto-js@4.2.1ein; dieses Paket installierte über einpostinstall-Skript einen Remote-Access-Trojaner (RAT) - Der RAT zielt auf macOS, Windows und Linux und kommuniziert mit dem C2-Server (Command and Control) (
sfrclak.com:8000), um Payloads der zweiten Stufe herunterzuladen - Nach der Installation löschte er den Schadcode und seine Spuren und ersetzte ihn durch eine saubere
package.json, um die forensische Erkennung zu umgehen
Zeitachse des Angriffs
-
- März, 05:57 UTC:
plain-crypto-js@4.2.0(saubere Version) veröffentlicht
- März, 05:57 UTC:
-
- März, 23:59 UTC:
plain-crypto-js@4.2.1(bösartige Version) veröffentlicht,postinstall-Hook hinzugefügt
- März, 23:59 UTC:
-
- März, 00:21 UTC:
axios@1.14.1veröffentlicht, bösartige Abhängigkeit eingeschleust
- März, 00:21 UTC:
-
- März, 01:00 UTC:
axios@0.30.4veröffentlicht, dieselbe bösartige Abhängigkeit eingeschleust
- März, 01:00 UTC:
-
- März, 03:15 UTC: npm entfernt beide bösartigen Versionen
-
- März, 04:26 UTC: npm ersetzt
plain-crypto-jsdurch einen Security-Holder-Stub (0.0.1-security.0)
- März, 04:26 UTC: npm ersetzt
Überblick über axios
- axios ist der am weitesten verbreitete HTTP-Client im JavaScript-Ökosystem und wird sowohl in Node.js als auch im Browser verwendet
- Mit mehr als 300 Millionen Downloads pro Woche kann bereits ein einziges bösartiges Release weitreichende Schäden verursachen
- Für normale Entwickler ist es bei
npm installschwer zu erkennen, dass bösartiger Code installiert wird
Phasen des Angriffs
-
Phase 1 — Übernahme des Maintainer-Kontos
- Die Angreifer kompromittierten das npm-Konto
jasonsaaymanund änderten die E-Mail-Adresse inifstap@proton.me - Anschließend veröffentlichten sie bösartige Builds sowohl für die 1.x- als auch die 0.x-Release-Branches
- Reguläre Releases werden über den OIDC Trusted Publisher von GitHub Actions veröffentlicht, doch
axios@1.14.1wurde manuell veröffentlicht und hat wedergitHeadnoch eine OIDC-Signatur - Vermutlich nutzten die Angreifer ein langlebiges npm-Access-Token
- Die Angreifer kompromittierten das npm-Konto
-
Phase 2 — Vorabveröffentlichung der bösartigen Abhängigkeit
plain-crypto-js@4.2.1wurde vom Kontonrwise@proton.meveröffentlicht- Es tarnte sich als
crypto-jsund verwendete dieselbe Beschreibung und dieselbe Repository-URL - Enthielt den Hook
"postinstall": "node setup.js", der bei der Installation automatisch ausgeführt wird - Nach dem Angriff wurde
package.mddurchpackage.jsonersetzt, um das Löschen von Beweismitteln vorzubereiten
-
Phase 3 — Einschleusen der Abhängigkeit in axios
plain-crypto-js@^4.2.1wurde als Runtime-Abhängigkeit hinzugefügt- Im Code selbst wird sie kein einziges Mal importiert → Phantom-Abhängigkeit
- Bei
npm installwird sie automatisch installiert und daspostinstall-Skript ausgeführt
Analyse des RAT-Droppers (setup.js)
-
Techniken zur Verschleierung
- Zeichenketten wurden verschlüsselt im Array
stq[]gespeichert und mit_trans_1(XOR) sowie_trans_2(Base64 + umgekehrte Reihenfolge) entschlüsselt - Die C2-URL lautet
http://sfrclak.com:8000/6202033 - Zu den entschlüsselten Zeichenketten gehören OS-Kennungen (
win32,darwin), Dateipfade und Shell-Befehle
- Zeichenketten wurden verschlüsselt im Array
-
Plattformabhängige Payloads
-
macOS
- AppleScript wird nach
/tmpgeschrieben und mitosascriptausgeführt - Eine RAT-Binärdatei wird vom C2 geladen, unter
/Library/Caches/com.apple.act.mondgespeichert und ausgeführt - Der Dateiname ist als Apple-System-Daemon getarnt
- AppleScript wird nach
-
Windows
- Nach dem PowerShell-Pfad wird gesucht, dann wird nach
%PROGRAMDATA%\wt.exekopiert - Über VBScript wird ein PowerShell-RAT vom C2 heruntergeladen und ausgeführt
- Temporäre Dateien (
.vbs,.ps1) werden nach der Ausführung gelöscht
- Nach dem PowerShell-Pfad wird gesucht, dann wird nach
-
Linux
- Mit
curlwird/tmp/ld.pyheruntergeladen und mitnohup python3ausgeführt - Die Datei
/tmp/ld.pybleibt zurück - Auf allen drei Plattformen werden POST-Bodies an
packages.npm.org/product0~2verwendet, um wie legitimer npm-Traffic auszusehen
- Mit
-
-
Selbstlöschung und Verschleierung
setup.jsundpackage.jsonwerden gelöschtpackage.mdwird durchpackage.jsonersetzt, um wie ein sauberes Paket zu wirken- Danach ist eine Erkennung per
npm auditoder manueller Prüfung nicht mehr möglich - Die Existenz von
node_modules/plain-crypto-js/bleibt jedoch ein Beleg für eine Infektion
Ausführungsvalidierung mit StepSecurity Harden-Runner
- Harden-Runner protokolliert in GitHub Actions Netzwerk-, Prozess- und Dateiereignisse in Echtzeit
- Bei der Installation von
axios@1.14.1wurden zwei C2-Verbindungen (curl,nohup) erkannt- Die erste Verbindung erfolgte 2 Sekunden nach dem Start von
npm install - Die zweite folgte 36 Sekunden später und lief als Hintergrundprozess weiter
- Die erste Verbindung erfolgte 2 Sekunden nach dem Start von
- Die Analyse des Prozessbaums zeigte, dass der
nohup-Prozess als verwaister Prozess unter PID 1 (init) zurückblieb und dauerhaft weiterlief - Im Dateiereignisprotokoll wurde
package.jsonzweimal überschrieben- Erstens: Schreiben der bösartigen Version während der Installation
- Zweitens: Ersetzung durch einen sauberen Stub 36 Sekunden später
Indicators of Compromise (IOC)
-
Bösartige npm-Pakete
- axios@1.14.1 · shasum: 2553649f232204966871cea80a5d0d6adc700ca
- axios@0.30.4 · shasum: d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71
- plain-crypto-js@4.2.1 · shasum: 07d889e2dadce6f3910dcbc253317d28ca61c766
-
Netzwerk
- C2-Domain: sfrclak.com
- IP: 142.11.206.73
- URL:
http://sfrclak.com:8000/6202033
-
Dateipfade
- macOS:
/Library/Caches/com.apple.act.mond - Windows:
%PROGRAMDATA%\wt.exe - Linux:
/tmp/ld.py
- macOS:
-
Angreiferkonten
jasonsaayman(kompromittierter Maintainer)nrwise(von den Angreifern erstelltes Konto)
-
Sichere Version
- axios@1.14.0 (sauber)
Überprüfung der Auswirkungen und Vorgehen zur Reaktion
- In
npm list axiosoder in derpackage-lock.jsonauf 1.14.1 / 0.30.4 prüfen - Prüfen, ob
node_modules/plain-crypto-jsvorhanden ist - Wenn RAT-Dateien je nach Betriebssystem vorhanden sind, von einer vollständigen Systemkompromittierung ausgehen
- In CI/CD-Logs prüfen, ob diese Versionen installiert wurden, und alle Geheimnisse und Tokens austauschen
Schritte zur Wiederherstellung
- axios auf eine sichere Version (1.14.0 oder 0.30.3) festsetzen
- Den Ordner
plain-crypto-jslöschen und mitnpm install --ignore-scriptsneu installieren - Falls Spuren des RAT gefunden werden, das System neu aufsetzen
- Alle Zugangsdaten (AWS, SSH, CI/CD usw.) rotieren
- CI/CD-Pipelines prüfen und Geheimnisse austauschen
- Bei automatisierten Builds die Option
--ignore-scriptsverwenden - C2-Domain/IP per Firewall oder
/etc/hostsblockieren
Funktionen von StepSecurity Enterprise
-
Harden-Runner
- Erzwingt in GitHub Actions eine Whitelist für ausgehenden Netzwerkverkehr
- Blockiert auffälligen Traffic und protokolliert ihn
- Hätte Verbindungen zu
sfrclak.com:8000vorab blockieren können
-
Dev Machine Guard
- Überwacht in Echtzeit npm-Pakete, die auf Entwickler-PCs installiert werden
- Erkennt Geräte mit installiertem
axios@1.14.1oder0.30.4sofort
-
npm Package Cooldown Check
- Führt für neu veröffentlichte Pakete eine temporäre Sperrfrist für Installationen ein
- Kann schnell veröffentlichte bösartige Pakete wie
plain-crypto-js@4.2.1erkennen
-
Compromised Updates Check
- Verhindert auf Basis einer Echtzeit-Datenbank bösartiger Pakete das Mergen von PRs
- Registriert
axios@1.14.1undplain-crypto-js@4.2.1sofort
-
Package Search
- Durchsucht PRs und Repositories in der gesamten Organisation nach der Einführung bestimmter Pakete
- Ermittelt den Umfang der Auswirkungen (Repositorys, Teams, PRs) sofort
-
AI Package Analyst
- Überwacht die npm-Registry in Echtzeit und erkennt verhaltensbasierte Malware
- Erkannte beide bösartigen Versionen innerhalb weniger Minuten nach der Veröffentlichung
-
Threat Center Alert
- Liefert Threat-Intel-Benachrichtigungen mit Angriffszusammenfassung, IOC und Reaktionsverfahren
- Sorgt durch SIEM-Integration für Echtzeit-Transparenz
Danksagung
- Die axios-Maintainer und die Community reagierten über GitHub issue #10604 schnell
- GitHub sperrte das kompromittierte Konto, und npm entfernte die bösartigen Versionen und setzte den Security-Holder ein
- Die koordinierte Reaktion von Maintainern, GitHub und npm minimierte den Schaden für Entwickler weltweit
2 Kommentare
Ich hätte nie gedacht, dass ein Paket dieser Größenordnung kompromittiert werden könnte, aber axios übertrifft wirklich jede Vorstellung.
Hacker-News-Kommentare
npm, bun, pnpm und uv unterstützen inzwischen alle die Festlegung eines Mindestzeitraums vor der Freigabe von Paketen
Ich habe
ignore-scripts=truein meiner~/.npmrceingetragen, und allein diese Einstellung hätte die Schwachstelle bereits entschärfen könnenbun und pnpm führen Lifecycle-Skripte standardmäßig nicht aus
Konfigurationsbeispiele für die einzelnen Paketmanager:
exclude-newer = "7 days"min-release-age=7minimum-release-age=10080minimumReleaseAge = 604800Interessanterweise verwendet jeder eine andere Zeiteinheit
Bei der Nutzung von LLM-Agenten kann diese Einstellung zu Fehlschlägen führen, daher sollte man entsprechende Hinweise in
AGENTS.mdoderCLAUDE.mdergänzentimeoutMinutesstatttimeoutmin-release-age=7 # dayswird womöglich nicht tatsächlich angewendet~/.yarnrc.ymlmitnpmMinimalAgeGate: "3d"setzenViele waren schockiert über die Nachricht, dass Axios einem Supply-Chain-Angriff ausgesetzt war
In Axios selbst befand sich kein Schadcode, aber es wurde eine gefälschte Abhängigkeit namens
plain-crypto-js@4.2.1eingeschleust, die über ein postinstall-Skript einen RAT (Remote Access Trojan) installierteFür Nutzer, die wie bei pnpm oder bun postinstall-Skripte manuell freigeben müssen, ist das immerhin eine gute Nachricht
Es gab die Behauptung, Paketmanager seien ein gescheitertes Experiment
Es gibt hochwertige C-Bibliotheken wie SQLite, die aus einer einzigen
.c-Datei bestehen; mit so einem Ansatz könnte man Probleme mit transitiven Abhängigkeiten vermeidenDer Großteil der Angriffsfläche entsteht durch solche indirekten Abhängigkeiten
Selbst OpenSSL wird wegen Problemen mit der Codequalität neu geschrieben, und bei JS ist die Erweiterung der Standardbibliothek schwierig, weshalb es eine Flut an Polyfills gibt
Stattdessen wurde vorgeschlagen, in Repositories wie npm die Qualitätsstandards zu verschärfen und nur verantwortungsvolle Maintainer zuzulassen
Es gab den zynischen Witz, man beginne den Tag mit der Begrüßung: „Welches npm-Paket wurde heute kompromittiert?“
Linux-Nutzern wurde empfohlen, bwrap zu verwenden, um die gesamte Build-Logik von npm, pip, cargo, gradle usw. zu sandboxen
bwrap bietet wie Docker eine isolierte Umgebung, benötigt aber keine Images. Auch Flatpak basiert auf derselben Technik
Bei Server-Deployments ist Container-Hardening wichtig, und entscheidend ist es, CI/CD-Umgebungen als nicht vertrauenswürdige Zone zu behandeln
Dieselbe Sandbox könne man auch für die Ausführung von AI verwenden
requireausgeführt werdenAngesichts der wiederkehrenden Abhängigkeitsprobleme gab es die Sorge, dass auch das Rust-Ökosystem irgendwann Ähnliches erleben könnte
Eine aufgeblähte Standardbibliothek ist schwer umsetzbar, aber es braucht ein verlässliches System zur Sicherung der Paketqualität
Dank AI sei dieser Mehraufwand inzwischen machbar, und eigentlich hätte man das schon früher so handhaben sollen
Wichtige Regeln, um die Gefährdung durch NPM-Supply-Chain-Angriffe zu minimieren
--frozen-lockfileböten ausreichend SchutzAuf die Frage „Wie kann man solche Angriffe vollständig vermeiden?“
kam die Meinung auf, man würde gern auf Qubes OS umsteigen, um Passwortmanager und Build-Umgebung vollständig zu trennen
Das wurde mit Schutzausrüstung (PPE) im Chemielabor verglichen: Auch in Entwicklungsumgebungen brauche man Isolation und Schutz
pip hat bereits begonnen, Installationen außerhalb von virtualenv zu blockieren, und man hofft, dass Paketmanager künftig eine Option zum Verweigern der Ausführung außerhalb einer Sandbox anbieten
pnpm und bun ignorieren inzwischen standardmäßig postinstall-Skripte, npm führt sie jedoch weiterhin aus
Es ist sinnvoll,
ignore-scripts=truein~/.npmrczu setzennpm verzeichnet weiterhin 80 Millionen Downloads pro Woche
Es wurde vermutet, dass der Verlust von Zugangsdaten in diesem Vorfall auf den früheren LiteLLM-Zwischenfall zurückgeht
Viele fühlen sich bei Python oder Node.js unwohl, empfinden das Problem aber letztlich als allgemein verbreitet