Der Vorfall, bei dem das Node.js-Paket Axios kompromittiert wurde, zeigt deutlich, welche Relevanz und Auswirkungen Supply-Chain-Angriffe haben können. In diesem Beitrag werden wir den Vorfall genauer untersuchen.

Das Axios npm-Paket

Axios (https://axios-http.com/) ist eine in JavaScript (Node.js) geschriebene HTTP-Client-Library, mit der Anwendungen Requests (z.B. GET, POST) an APIs oder Webserver senden können. Dabei übernimmt Axios Funktionen wie Header-Handling, JSON-Verarbeitung sowie Fehler- und Timeout-Behandlung. Typischerweise wird es genutzt, um externe Services anzusprechen, Daten auszutauschen oder Automatisierungen umzusetzen. Axios hat eine relativ hohe Verbreitung und wird laut https://www.npmjs.com/package/axios ca. 60 bis 90 Millionen Mal pro Woche heruntergeladen und wird von 170.000 anderen Paketen als Abhängigkeit genutzt. Die Library wird von vielen Web-Projekten, in CI/CD-Pipelines oder auch bei Cloud-Anbietern verwendet.

Angriffsvektor im Detail

Angreifer haben Kontrolle über das Repository eines Maintainers von Axios erlangt und die Abhängigkeiten, also die npm-Pakete, die Axios selbst benötigt, verändert. Hinzugefügt wurde das npm-Paket plain-crypto-js, das bewusst eine namentliche Ähnlichkeit zum bekannten Paket crypto-js aufweist. Dies kann bereits als Typosquatting oder Combosquatting bezeichnet werden. Im Paket plain-crypto-js befand sich ein postinstall-Hook, der nach der Installation des Pakets automatisch das Skript setup.js ausführt. Postinstall-Hooks sind eine reguläre Funktion von npm, die dazu dienen, Buildprozesse besser automatisieren zu können. Dieses Skript identifiziert das Betriebssystem, nimmt Kontakt zu einem C&C-Server (Command-and-Control-Server) auf und lädt einen passenden RAT (Remote-Access-Trojaner) herunter. Da die postinstall-Hooks mit den Berechtigungen des Benutzers laufen, verfügte das Skript in den meisten Fällen über ausreichende Berechtigungen.

Wie das Skript Kontakt mit dem C&C-Server aufgenommen hat, ist ebenfalls interessant, da es sich sehr gut tarnen konnte. Zeichenketten wurden in umgekehrter Reihenfolge gespeichert und bestimmte Zeichen, wie zum Beispiel Gleichheitszeichen (=), wurden durch Unterstriche (_) ersetzt. Anschließend wurden die Zeichenketten mit zwei unterschiedlichen XOR-Verknüpfungen verschlüsselt. Durch diese Zeichenumkehr und XOR-Verschlüsselung konnten automatisierte Tools zur Codeanalyse den Code nicht lesen und analysieren. Die Verbindung zum C&C-Server erfolgte über Port TCP/8000 via HTTP, also unverschlüsselt. Da die Kommunikation unverschlüsselt erfolgte, konnte das Skript SSL-Inspektion und Zertifikat-Pinning umgehen. Zudem verwendete das Skript den User-Agent des Internet Explorer 8. Dies kann ebenfalls dabei helfen, Sicherheitssoftware in Unternehmen zu umgehen, da bei älteren Browsern teils Ausnahmen gemacht werden und bestimmte Regeln nicht greifen. Nachdem das Skript den RAT vom C&C-Server heruntergeladen hatte, löschte es sich selbst, um Spuren zu beseitigen.

Social-Engineering-Angriff auf Maintainer

Ein weiterer sehr interessanter Punkt ist, wie die Angreifer Zugriff auf das Repository von Axios erlangt haben. Auf GitHub gibt es ein Post-Mortem-Ticket zu diesem Vorfall. Demnach wurde der Entwickler von Personen angesprochen, die sich als Mitarbeiter einer Firma ausgaben. Sie luden ihn in einen Slack-Chat ein, der optisch und von den Channels her an den der Organisation angelehnt war. Anscheinend ging es dabei um einen Termin für einen Podcast. Bei einem Videocall mit den Angreifern erschien beim Maintainer von Axios ein Fenster, das ihn aufforderte, wegen Audioproblemen etwas zu installieren. Vermutlich nutzten die Angreifer einen BitB-Angriff (Browser-in-the-Browser), um ein gefälschtes Fenster einzublenden. Dies führte dazu, dass ein RAT auf dem Rechner installiert wurde. Dieser entwendete Session-Token, sodass die Angreifer ohne MFA Änderungen am Repository durchführen konnten.

Die Änderungen am Axios-Paket wurden glücklicherweise innerhalb von 3 Stunden entdeckt und konnten schnell rückgängig gemacht werden. Der Fall zeigt aber deutlich, wie fragil Paketverwaltungen wie npm aufgrund der verflochtenen Abhängigkeiten sind und wie gefährlich es ist, wenn Updates ohne Hinterfragen automatisch installiert werden.

Nach dem Angriff stellte sich heraus, dass wohl mehrere Entwickler anderer Pakete nach demselben Schema kontaktiert worden waren. Dass Axios kompromittiert wurde, war also kein Einzelfall oder Zufall, sondern das Ergebnis eines gezielten und geplanten Angriffs. Das Muster dieses Social-Engineering-Angriffs entsprach dem der nordkoreanischen APT UNC1069 (teilweise auch CryptoCore genannt). Es ist stark davon auszugehen, dass hinter einem solchen koordinierten Angriff ein staatlicher Akteur steckt.

Schutzmaßnahmen

Die abschließende Frage lautet: Wie kann man sich vor solchen Angriffen schützen? Die Antwort ist vielschichtig, denn kein einzelnes Tool oder Feature hätte den Axios-Compromise vollständig verhindert – aber mehrere Maßnahmen in Kombination hätten die Angriffsfläche drastisch reduziert.

Grundsätzlich sollten npm-Pakete in Produktionsumgebungen und CI/CD-Pipelines niemals automatisch auf die neueste Version aktualisiert werden. Die Verwendung von Caret (^) oder Tilde (~) in der package.json erlaubt npm, Minor- oder Patch-Updates stillschweigend einzuspielen – genau das wurde beim Axios-Angriff ausgenutzt, da sowohl der latest- als auch der legacy-Tag auf die kompromittierten Versionen zeigten. Stattdessen sollten exakte Versionen gepinnt und Updates manuell oder über kontrollierte Prozesse eingespielt werden.

Der gesamte Infektionspfad lief über einen postinstall-Hook in plain-crypto-js, der eine setup.js Datei ausführte. Innerhalb von zwei Sekunden nach npm install kommunizierte die Malware bereits mit dem C&C-Server – noch bevor npm die Dependency-Auflösung abgeschlossen hatte. Mit npm ci –ignore-scripts oder der globalen Konfiguration npm config set ignore-scripts true wäre dieser Angriffsvektor vollständig neutralisiert worden. Das ist die wirksamste Einzelmaßnahme.

Auch das neue Paket plain-crypto-js war verdächtig: Es hatte keine nennenswerte Historie, Version 4.2.0 wurde erst 18 Stunden vor dem eigentlichen Angriff veröffentlicht – mutmaßlich, um „brandneues Paket"-Alarme von Sicherheitsscannern zu umgehen. Seit npm v11.10.0 existiert mit min-release-age ein Feature, das genau dieses Problem adressiert. Die Konfiguration npm config set min-release-age=7 bewirkt, dass npm keine Pakete installiert, die weniger als 7 Tage alt sind. Damit hätten weder die manipulierten Axios-Versionen noch die vorgeschaltete Dependency automatisch eingespielt werden können.

Manuelle Reviews skalieren nicht – automatisierte Tools schon. Man kann sich natürlich manuell anschauen, was sich bei Updates geändert hat. In der Praxis skaliert das aber nicht – erst recht nicht bei großen oder stark automatisierten Infrastrukturen, in denen Dutzende transitiver Abhängigkeiten bei jedem Build aufgelöst werden. Hier setzen spezialisierte Tools an:

  • Socket.dev wrappt den npm install-Befehl transparent und analysiert Pakete vor der Installation per statischer Analyse auf verdächtige Muster: neue Install-Scripts, obfuskierter Code, Netzwerkzugriffe, Zugriffe auf Umgebungsvariablen. Socket hätte plain-crypto-js sofort geflaggt.
  • StepSecurity Harden-Runner überwacht in GitHub Actions auf Kernel-Ebene jede ausgehende Netzwerkverbindung und jeden gestarteten Prozess – dieses Tool hat den Axios-Compromise in der Praxis als erstes erkannt.
  • Snyk und vergleichbare SCA-Tools (Software Composition Analysis) scannen Dependency-Trees gegen bekannte Advisories. Allerdings mit einer wichtigen Einschränkung: npm audit und klassische CVE-basierte Scanner erkennen nur bekannte Schwachstellen – Zero-Day-Angriffe wie der auf Axios fallen durch dieses Raster, solange kein Advisory existiert.
  • SLSA Provenance Verification prüft, ob ein Paket über eine verifizierte CI/CD-Pipeline veröffentlicht wurde. Beim Axios-Angriff fehlte die SLSA-Provenance bei den kompromittierten Versionen – ein klarer Indikator, der automatisiert hätte erkannt werden können.

Interne Registry-Proxies als Gatekeeper. Lösungen wie JFrog Artifactory oder Sonatype Nexus können als Zwischenschicht zwischen der öffentlichen npm-Registry und den internen Entwicklungsumgebungen fungieren. Dort lassen sich Policies durchsetzen – Mindestalter, Provenance-Checks, Blocklisten –, bevor ein Paket überhaupt in die interne Registry gelangt.

Die Kombination aus Dependency Pinning, deaktivierten Lifecycle-Hooks, Cooldown-Policies und automatisierter Supply-Chain-Überwachung bildet einen Defense-in-Depth-Ansatz, der die meisten aktuellen Angriffsvektoren abdeckt. Keine einzelne Maßnahme ist ausreichend, aber jede Schicht erhöht den Aufwand für Angreifer erheblich.

Quellensammlung: