12 Punkte von GN⁺ 29 일 전 | 2 Kommentare | Auf WhatsApp teilen
  • 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 per postinstall-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.1 ein; dieses Paket installierte über ein postinstall-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

    1. März, 05:57 UTC: plain-crypto-js@4.2.0 (saubere Version) veröffentlicht
    1. März, 23:59 UTC: plain-crypto-js@4.2.1 (bösartige Version) veröffentlicht, postinstall-Hook hinzugefügt
    1. März, 00:21 UTC: axios@1.14.1 veröffentlicht, bösartige Abhängigkeit eingeschleust
    1. März, 01:00 UTC: axios@0.30.4 veröffentlicht, dieselbe bösartige Abhängigkeit eingeschleust
    1. März, 03:15 UTC: npm entfernt beide bösartigen Versionen
    1. März, 04:26 UTC: npm ersetzt plain-crypto-js durch einen Security-Holder-Stub (0.0.1-security.0)

Ü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 install schwer zu erkennen, dass bösartiger Code installiert wird

Phasen des Angriffs

  • Phase 1 — Übernahme des Maintainer-Kontos

    • Die Angreifer kompromittierten das npm-Konto jasonsaayman und änderten die E-Mail-Adresse in ifstap@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.1 wurde manuell veröffentlicht und hat weder gitHead noch eine OIDC-Signatur
    • Vermutlich nutzten die Angreifer ein langlebiges npm-Access-Token
  • Phase 2 — Vorabveröffentlichung der bösartigen Abhängigkeit

    • plain-crypto-js@4.2.1 wurde vom Konto nrwise@proton.me veröffentlicht
    • Es tarnte sich als crypto-js und 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.md durch package.json ersetzt, um das Löschen von Beweismitteln vorzubereiten
  • Phase 3 — Einschleusen der Abhängigkeit in axios

    • plain-crypto-js@^4.2.1 wurde als Runtime-Abhängigkeit hinzugefügt
    • Im Code selbst wird sie kein einziges Mal importiert → Phantom-Abhängigkeit
    • Bei npm install wird sie automatisch installiert und das postinstall-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
  • Plattformabhängige Payloads

    • macOS

      • AppleScript wird nach /tmp geschrieben und mit osascript ausgeführt
      • Eine RAT-Binärdatei wird vom C2 geladen, unter /Library/Caches/com.apple.act.mond gespeichert und ausgeführt
      • Der Dateiname ist als Apple-System-Daemon getarnt
    • Windows

      • Nach dem PowerShell-Pfad wird gesucht, dann wird nach %PROGRAMDATA%\wt.exe kopiert
      • Über VBScript wird ein PowerShell-RAT vom C2 heruntergeladen und ausgeführt
      • Temporäre Dateien (.vbs, .ps1) werden nach der Ausführung gelöscht
    • Linux

      • Mit curl wird /tmp/ld.py heruntergeladen und mit nohup python3 ausgeführt
      • Die Datei /tmp/ld.py bleibt zurück
      • Auf allen drei Plattformen werden POST-Bodies an packages.npm.org/product0~2 verwendet, um wie legitimer npm-Traffic auszusehen
  • Selbstlöschung und Verschleierung

    • setup.js und package.json werden gelöscht
    • package.md wird durch package.json ersetzt, um wie ein sauberes Paket zu wirken
    • Danach ist eine Erkennung per npm audit oder 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.1 wurden 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 Analyse des Prozessbaums zeigte, dass der nohup-Prozess als verwaister Prozess unter PID 1 (init) zurückblieb und dauerhaft weiterlief
  • Im Dateiereignisprotokoll wurde package.json zweimal ü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

  • Dateipfade

    • macOS: /Library/Caches/com.apple.act.mond
    • Windows: %PROGRAMDATA%\wt.exe
    • Linux: /tmp/ld.py
  • 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 axios oder in der package-lock.json auf 1.14.1 / 0.30.4 prüfen
  • Prüfen, ob node_modules/plain-crypto-js vorhanden 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

  1. axios auf eine sichere Version (1.14.0 oder 0.30.3) festsetzen
  2. Den Ordner plain-crypto-js löschen und mit npm install --ignore-scripts neu installieren
  3. Falls Spuren des RAT gefunden werden, das System neu aufsetzen
  4. Alle Zugangsdaten (AWS, SSH, CI/CD usw.) rotieren
  5. CI/CD-Pipelines prüfen und Geheimnisse austauschen
  6. Bei automatisierten Builds die Option --ignore-scripts verwenden
  7. C2-Domain/IP per Firewall oder /etc/hosts blockieren

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:8000 vorab 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.1 oder 0.30.4 sofort
  • 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.1 erkennen
  • Compromised Updates Check

    • Verhindert auf Basis einer Echtzeit-Datenbank bösartiger Pakete das Mergen von PRs
    • Registriert axios@1.14.1 und plain-crypto-js@4.2.1 sofort
  • 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

 
chanapple 29 일 전

Ich hätte nie gedacht, dass ein Paket dieser Größenordnung kompromittiert werden könnte, aber axios übertrifft wirklich jede Vorstellung.

 
GN⁺ 29 일 전
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=true in meiner ~/.npmrc eingetragen, und allein diese Einstellung hätte die Schwachstelle bereits entschärfen können
    bun und pnpm führen Lifecycle-Skripte standardmäßig nicht aus
    Konfigurationsbeispiele für die einzelnen Paketmanager:

    • uv: exclude-newer = "7 days"
    • npm: min-release-age=7
    • pnpm: minimum-release-age=10080
    • bun: minimumReleaseAge = 604800
      Interessanterweise 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.md oder CLAUDE.md ergänzen
    • Auf die Bemerkung „alle haben unterschiedliche Zeiteinheiten“ folgte der Witz: „Ist das dein erster Tag mit JavaScript?
    • pnpm hat diese Funktion als erstes eingeführt. npm unterstützt sie nur ab 11.10.0, also seit dem Release vom 11. Februar 2026
    • Es gab auch die Meinung, dass man Einheiten besser direkt im Konfigurationsnamen angeben sollte, zum Beispiel timeoutMinutes statt timeout
    • npm unterstützt möglicherweise keine Kommentare. min-release-age=7 # days wird womöglich nicht tatsächlich angewendet
    • Bei Yarn Berry lässt sich das in ~/.yarnrc.yml mit npmMinimalAgeGate: "3d" setzen
  • Viele 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.1 eingeschleust, die über ein postinstall-Skript einen RAT (Remote Access Trojan) installierte
    Für Nutzer, die wie bei pnpm oder bun postinstall-Skripte manuell freigeben müssen, ist das immerhin eine gute Nachricht

    • fetch ist in Node.js erst seit v18 standardmäßig enthalten, stabil wurde es ab v21. Axios existiert schon viel länger und ist weiterhin weit verbreitet, weil es in vielen Frameworks und Tutorials enthalten ist
    • Auf die Aussage „pnpm-/bun-Nutzer sind sicher“ kam die Frage auf, ob man das in älteren Versionen nicht wahrscheinlich bereits freigegeben hätte
    • Es wurde gefragt, ob pnpm auch postinstall-Skripte transitiver Abhängigkeiten blockiert
  • 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 vermeiden
    Der Großteil der Angriffsfläche entsteht durch solche indirekten Abhängigkeiten

    • Paketmanager sind inzwischen ein unverzichtbarer Bestandteil der Sprachadoption. Das Problem ist das Fehlen von Qualitätskontrolle und die Anreizstruktur
      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
    • Es gab auch die Ansicht, dass die Community keine Lösung akzeptieren wird, die etwas mehr Aufwand erfordert
      Stattdessen wurde vorgeschlagen, in Repositories wie npm die Qualitätsstandards zu verschärfen und nur verantwortungsvolle Maintainer zuzulassen
    • In der Webentwicklung ist die Angriffsfläche viel größer. Das manuelle Kopieren erschwert das Nachverfolgen von Updates, daher sind Benachrichtigungsfunktionen von Paketmanagern weiterhin nützlich
    • Es wurde auch angemerkt, dass vor allem NPM ein Ökosystem sei, in dem Supply-Chain-Angriffe besonders gravierend sind
    • Dem wurde entgegengehalten, Rust sei sicherer als C, und die meisten Crates seien von hoher Qualität, weshalb die Fixierung auf C-Bibliotheken übertrieben sei
  • 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

    • Allerdings wurde darauf hingewiesen, dass dieser Ansatz nur gegen postinstall-Angriffe wirksam ist. Code kann bereits beim bloßen require ausgeführt werden
    • Jemand hatte auch die Docker-basierte persönliche Sandbox amazing-sandbox entwickelt
    • Empfohlen wurde außerdem drop, ein höherwertiges Tool als bwrap
    • Manche meinten, firejail sei eine flexiblere Sicherheits-Sandbox
    • Es wurde auch angemerkt, dass SSH-Socket-Forwarding keinen Sicherheitsvorteil bringt, weil es Zugriff auf den privaten Schlüssel erlaubt; passwortgeschützte Schlüssel seien besser
  • Angesichts 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

    • Es wurde vorgeschlagen, dass bei großen Paketen wie Axios mehrere MFA-autorisierte Personen Veröffentlichungen freigeben müssen
    • Es wurde auch prognostiziert, dass kommerzielle Dienste für verifizierte Abhängigkeiten entstehen werden
    • Ein weiterer Vorschlag war, Tests von Abhängigkeiten direkt zu kopieren und in die eigene Codebasis aufzunehmen und dann den eigenen Code-Review-Prozess darauf anzuwenden
      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

    • Nutzung des Zero-Installs-Modus von Yarn
    • postinstall-Skripte deaktivieren oder vor der Ausführung prüfen
    • Wenn während der Entwicklung Third-Party-Code ausgeführt wird, nur innerhalb einer VM oder eines Containers
    • Beim Hinzufügen von Paketen gilt: Popularität ist ein Plus, frische Commits eher ein Minus; Code und Änderungshistorie sollten direkt geprüft werden
    • Der gesamte Abhängigkeitsbaum sollte validiert werden, und bei jedem neuen Entwickler müsse das Vertrauensniveau neu bewertet werden
    • Manche meinten, schon lockfiles und die Option --frozen-lockfile böten ausreichend Schutz
    • Andere vertreten die einfache, aber wirkungsvolle Philosophie: „Ich meide einfach problematische Stacks
  • Auf 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

    • Ein Team führt npm-bezogene Arbeiten nur noch in Apple-Containern aus und plant dasselbe auch für Python und Rust
      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
    • Manche installieren Node.js/npm überhaupt nicht auf dem System. Sie hätten bislang keinen Fall erlebt, in dem das zwingend nötig gewesen wäre
  • pnpm und bun ignorieren inzwischen standardmäßig postinstall-Skripte, npm führt sie jedoch weiterhin aus
    Es ist sinnvoll, ignore-scripts=true in ~/.npmrc zu setzen
    npm 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

    • Die Einstellung eines Mindestzeitraums vor Releases hilft zwar, aber viele haben weiterhin Angst vor Abhängigkeits-Updates
    • Andere meinen, nicht LiteLLM, sondern eher der Trivy-Vorfall sei die eigentliche Ursache gewesen
    • Vorgeschlagen wurde auch, alles in rootlosen temporären Containern auszuführen, um den Schaden zu begrenzen