← Kompendium

Warum „wir scannen nach dem Git Commit" für Supply Chain Security nicht reicht

Ein kompromittiertes npm-Paket wird nicht erst gefährlich, wenn es im Repository landet, sondern in dem Moment, in dem ein Entwickler es lokal installiert. Wer Supply Chain ernst nimmt, muss deshalb nicht fragen „Haben wir gescannt?", sondern „Können wir innerhalb von Minuten unseren Blast Radius bestimmen?", und das ist eine organisatorische Frage, keine reine Tool-Frage.

Wo der Angriff wirklich beginnt

Die meisten Sicherheitsprozesse setzen dort an, wo Code das Team verlässt: beim Commit, beim Merge, in der Pipeline. Der Blick richtet sich auf das, was ins Repository und weiter nach Production wandert. Genau diese Reihenfolge führt bei Supply-Chain-Angriffen in die Irre, weil ein manipuliertes Paket seine Wirkung schon eine Station früher entfaltet.

Der kritische Moment ist der lokale `npm install` auf dem Rechner eines Entwicklers, lange bevor eine Zeile Code committet wird. Manche Pakete bringen ein Install-Skript mit, das schon beim Entpacken automatisch ausgeführt wird, sodass fremder Code läuft, noch bevor jemand die Bibliothek überhaupt benutzt. Ein Scanner, der erst nach dem Commit greift, sieht davon nichts.

Das Install-Skript ist dabei nur der früheste Auslöser, nicht die einzige Gefahr. Auch der eigentliche Paketcode kann als Credential Stealer präpariert sein und schlägt dann zu, sobald man die Bibliothek importiert und ausführt. Ein solches Paket läuft im selben Prozess wie das eigene Programm und darf grundsätzlich alles, was auch der Entwickler oder der ausführende Dienst darf, denn eine Sprachlaufzeit wie Node trennt vertrauenswürdigen von eingekauftem Code nicht von sich aus.

Was ein bösartiges Paket mitnimmt

Läuft dieser Code, hat er Zugriff auf alles, was der Entwickler auch hat. Er liest lokale Tokens, SSH-Keys, Cloud-Credentials, aktive Browser-Sessions, `.env`-Dateien und GitHub-Zugänge aus und schickt sie an den Angreifer, während der eigentliche Build oder Programmlauf für den Entwickler ganz normal aussieht. Damit ist nicht nur die Pipeline betroffen, sondern der Arbeitsplatz selbst wird zum Teil des Angriffswegs.

Diese Vertrauensentscheidung wird gerade dünner, statt strenger. Beim Vibe Coding trifft sie heute bei vielen Entwicklern nicht mehr ein Mensch, sondern ein Sprachmodell, das anhand einer Paketbeschreibung entscheidet, eine Abhängigkeit zu installieren und einzubinden. Wo früher wenigstens jemand kurz auf Name, Herkunft und Verbreitung geschaut hat, genügt dem Assistenten oft die plausible Beschreibung, sodass ein glaubwürdig getarntes Paket den Weg auf den Rechner findet, ohne dass ein Mensch die Installation je bewusst freigegeben hat.

Die saubere Trennung zwischen Entwicklung und Produktion bleibt wichtig, reicht aber nicht aus, weil die Beute auf dem Entwicklerrechner auch ohne Produktions-Credentials wertvoll ist. Selbst wenn die Produktionszugänge sauber getrennt liegen, kann Quellcode abfließen, können interne Repositories gelesen werden, und die Dev-Credentials genügen, um eigene Pakete, CI-Konfigurationen oder Repositories zu manipulieren.

Die zentrale Frage lautet deshalb nicht mehr, ob eine Library aktuell in Production läuft, sondern welche Library in welcher Version wann auf welchem Entwicklerrechner installiert war.

s1ngularity, Schritt für Schritt

Wie das in der Praxis abläuft, hat der s1ngularity-Angriff im August 2025 vorgeführt, und es lohnt sich, ihn einmal durchzuspielen. Am Anfang stand kein spektakulärer Einbruch, sondern eine Schwachstelle in einem GitHub-Actions-Workflow des Nx-Projekts, über die sich Angreifer den npm-Publishing-Token beschafften.

Mit diesem Token veröffentlichten sie für rund vier Stunden manipulierte Versionen mehrerer Nx-Pakete auf npm. Wer in diesem Fenster installierte, führte ein Skript aus, das den lokalen Rechner nach Zugangsdaten durchsuchte und die Funde in öffentlich sichtbare GitHub-Repositories unter dem Account des Opfers hochlud.

Das Ausmaß wurde erst danach sichtbar: Nach Auswertung mehrerer Sicherheitsforscher wurden auf diesem Weg rund 2.349 Zugangsdaten offengelegt, darunter GitHub- und npm-Tokens, SSH-Keys und Cloud- sowie KI-Credentials. Ein Teil davon war noch gültig, nachdem die betroffenen Repositories bereits aufgeräumt waren, weil eine Bereinigung ohne Rotation die gestohlenen Schlüssel nicht entwertet.

Wenn das Paket sich selbst weiterträgt

Wenige Wochen später verschärfte sich das Muster. Im September 2025 tauchte mit „Shai-Hulud" ein sich selbst replizierender Wurm auf, der nicht ein einzelnes Paket manipulierte, sondern die gestohlenen Zugangsdaten eines kompromittierten Maintainers gleich nutzte, um dessen weitere Pakete zu verseuchen. Die zuständige US-Behörde CISA meldete über 500 betroffene npm-Pakete, und in einer zweiten Welle im November 2025 waren es erneut hunderte Pakete samt zehntausender GitHub-Repositories innerhalb weniger Stunden.

Der Unterschied zum klassischen Angriff ist entscheidend: Ein Wurm wartet nicht auf manuelle Verbreitung, sondern springt automatisch von einem Paket zum nächsten, solange er gültige Credentials findet. Damit wird die Zeit, in der ein manipuliertes Paket im Umlauf ist, kürzer und die Zahl der Betroffenen größer, während sich das Zeitfenster für eine Reaktion weiter zusammenzieht.

Die eigentliche Frage: der Blast Radius

Wenn morgen bekannt wird, dass eine Paketversion nur für wenige Stunden manipuliert war, entscheidet nicht der Scanner darüber, wie gut man dasteht, sondern die Fähigkeit, den eigenen Blast Radius zu bestimmen. Gemeint ist die Frage, wie weit der Schaden reicht: Hatte jemand im Team diese Version installiert, welche Secrets lagen auf dem betroffenen Rechner, und wurden damit anschließend Pushes, Releases oder CI-Läufe ausgelöst?

Erst die Antwort darauf entscheidet, ob ein Patch genügt oder ob rotiert, gesperrt, forensisch geprüft und ein Repository als potenziell kompromittiert behandelt werden muss. Diese Frage ist organisatorischer Natur, denn sie setzt voraus, dass irgendwo verlässlich festgehalten ist, wer welche Abhängigkeit wann bezogen hat, und zwar auch dann, wenn nie ein Commit daraus entstanden ist.

Warum Scannen nur eine Schicht ist

Damit verschiebt sich auch die Rolle des CVE. Ein CVE ist nicht der Moment, in dem eine Schwachstelle entsteht, sondern der Moment, in dem eine bereits vorhandene Lücke öffentlich dokumentiert wird. Ab da wissen deutlich mehr Menschen davon, und fertige Exploits werden schneller reproduzierbar, weshalb Reaktionsgeschwindigkeit weniger vom Werkzeug abhängt als vom Wissen darüber, was man einsetzt und wo.

NIS2 und ISO 27001 helfen an dieser Stelle nur dann, wenn sie nicht bei Papier stehen bleiben, sondern Risiken sichtbar machen, Verantwortlichkeiten klären, Asset- und Dependency-Inventare aufbauen und Incident-Prozesse einüben. Code Review und das Scanning in der CI/CD-Pipeline bleiben dabei sinnvoll, decken aber nur eine Schicht ab, weil sie den lokalen Install und die Frage nach dem Blast Radius nicht beantworten.

Was das konkret heißt

Wer Supply Chain ernst nimmt, kombiniert deshalb mehrere Ebenen, statt sich auf den Scanner zu verlassen. Auf der technischen Seite gehören gehärtete Entwicklerrechner dazu, getrennte Credentials und kurzlebige Tokens, Kontrolle über Lockfile und Registry, Software-Inventare bis hinunter zu den Abhängigkeiten sowie eine Erkennung, die auffällt, wenn ein Rechner ungewöhnliche Zugriffe zeigt. Auf der organisatorischen Seite braucht es klare Runbooks, die im Ernstfall eine schnelle Rotation und Sperrung von Zugängen erlauben.

Der Kern all dessen ist Sichtbarkeit darüber, was tatsächlich bezogen wurde, und genau daran arbeiten wir mit unserem Produkt Driftguard, das sich derzeit in einer geschlossenen Beta befindet. Auf der Roadmap steht ein npm-Proxy, über den sich der Blast Radius bestimmen lässt, also nachvollziehen, wer welches Paket in welchem Projekt geladen hat, auch ohne Git-Commit, und über den sich zugleich steuern lässt, welche Pakete und Versionen überhaupt freigegeben sind.

Wenn du deine aktuelle Sicherheitslage einmal ehrlich einordnen möchtest, schauen wir gemeinsam drauf, pragmatisch, hands-on und ohne Buzzword-Bingo. Meistens beginnt der nächste Schritt nicht mit einem großen Projekt, sondern damit, den eigenen Blast Radius überhaupt sichtbar zu machen.

Häufige Fragen

Reicht ein Scan im CI/CD nicht aus?

Nein. Ein kompromittiertes Paket wirkt schon beim lokalen `npm install` über sein Install-Skript oder spätestens dann, wenn der Paketcode importiert und ausgeführt wird, also bevor Code je das Repository erreicht. Scanning ist eine sinnvolle Schicht, beantwortet aber nicht, wer welche Version wann installiert hatte.

Was heißt „Blast Radius bestimmen"?

Schnell beantworten zu können, wer im Team eine betroffene Paketversion installiert hatte, welche Secrets dort lagen und ob damit Pushes, Releases oder CI-Läufe passierten. Erst das entscheidet, ob man nur patcht oder rotieren, sperren und forensisch prüfen muss.

Was war der Unterschied zwischen s1ngularity und Shai-Hulud?

Bei s1ngularity (August 2025) veröffentlichten Angreifer über einen erbeuteten Publishing-Token für einige Stunden manipulierte Nx-Pakete und griffen dabei rund 2.349 Zugangsdaten ab. Shai-Hulud (ab September 2025) war ein sich selbst replizierender Wurm, der mit gestohlenen Credentials automatisch weitere Pakete verseuchte und so hunderte Pakete traf.

Was ändert Vibe Coding an der Lage?

Die Vertrauensentscheidung über eine Abhängigkeit trifft zunehmend nicht mehr ein Mensch, sondern ein Sprachmodell anhand der Paketbeschreibung. Damit fällt die kurze menschliche Prüfung von Name, Herkunft und Verbreitung oft weg, und ein glaubwürdig getarntes Paket landet auf dem Rechner, ohne dass jemand die Installation bewusst freigegeben hat. Das macht Freigabe-Regeln für Pakete und einen bestimmbaren Blast Radius wichtiger, nicht unwichtiger.

Helfen NIS2 und ISO 27001 dabei?

Nur, wenn sie nicht als Papier enden. Richtig genutzt schaffen sie Asset- und Dependency-Inventare, klare Verantwortlichkeiten und geübte Incident-Prozesse, also genau das, was die Reaktionsgeschwindigkeit im Ernstfall ausmacht.

Ähnliche Themen