Du hast alles richtig gemacht, und deine Supply Chain wurde trotzdem kompromittiert

Stell dir das vor.
Du bist Senior Engineer in einer Firma, die Security ernst nimmt. Du hältst dich an die Regeln zur Dependency-Hygiene, die der Branche seit Jahren eingebläut werden. Jeden Dienstagmorgen öffnet ein Dependency-Bot Pull Requests. Du pinnst deine Software-Versionen, du nutzt nie :latest. Du hast Service Accounts nach dem Least-Privilege-Prinzip eingerichtet, verlangst bei jeder Änderung Code Review und scannst jeden Container auf Schwachstellen. Du liest sogar die Changelogs.
An einem Dienstagmorgen landet ein Pull Request. Ein kleiner Versionssprung für deinen Vulnerability Scanner: chore: bump trivy-action to v0.35.0. Ein Patch-Bump bei einem vertrauenswürdigen Tool. Die CI meldet lauter grüne Checks, das Changelog wirkt plausibel. Sicher zu mergen?
Du klickst auf Merge.
Innerhalb von Minuten sind alle Secrets in deiner CI-Umgebung in der Hand des Angreifers. Der Scanner, dem du das Finden von Schwachstellen anvertraut hast, wurde selbst zur Schwachstelle.
Das ist nicht hypothetisch. Genau das ist am 19. März 2026 dutzenden Organisationen passiert, als Angreifer Trivy kompromittierten, einen der meistgenutzten Security Scanner für Container, und ihn in ein Auslieferungswerkzeug für einen professionellen Credential Stealer verwandelten.
Teil 1: Du hast alles richtig gemacht, und es ist trotzdem passiert
Das ist keine Geschichte über Fahrlässigkeit. Teams, die das Richtige taten (Dependency-Bot, gepinnte Image-Versionen, Code Reviews, Least Privilege, Vulnerability Scanning und so weiter), wurden trotzdem getroffen. Dieser Angriff zielte nicht auf ihren Code. Er zielte auf ein Tool, dem sie vertrauten.
Das ist kein Einzelfall. Und die Abstände werden kürzer.
Der Trivy-Angriff war am 19. März. Innerhalb von Wochen wurden mit demselben Muster SAPs Open-Source-Pakete und PyTorch Lightning kompromittiert. Mitte Mai infizierte der erste selbstverbreitende Wurm 172 Pakete in 48 Stunden, und sein Quellcode ist inzwischen öffentlich, für jeden Angreifer zur Wiederverwendung. Tage später schleuste eine automatisierte Kampagne in sechs Stunden bösartige Änderungen in über 5.500 GitHub-Projekte, ein gekapertes Maintainer-Konto veröffentlichte 637 vergiftete Paketversionen in 22 Minuten, und GitHub selbst bestätigte rund 3.800 gestohlene interne Repositories, nachdem eine bösartige Editor-Extension die Zugangsdaten eines Engineers abgegriffen hatte.
Dann kam TrapDoor am 22. Mai. Es legt versteckte Instruktionsdateien ab, die KI-Coding-Assistants als Konfiguration einlesen. Die Instruktionen versuchen, die KI dazu zu bringen, einen gefälschten "Security Scan" auszuführen, der in Wahrheit Zugangsdaten stiehlt. Wenn der Assistant ohne menschliche Aufsicht mitspielt, erledigt er die Arbeit des Angreifers. Der KI-Assistent in deinem Editor ist jetzt Teil der Angriffsfläche.
Deshalb haben wir schon früher einen Post über KI-gestützte Entwicklung und die Bedeutung menschlicher Aufsicht in Engineering-Workflows geschrieben. Ohne menschliche Verifikation können autonome Aktionen Lücken hinterlassen, die genau solche Angriffe ausnutzen.
Auto-Execute-Primitiven kommen ständig neu dazu. Die Liste wird nie vollständig sein.
Teil 2: Wie der Angriff funktionierte
Die Falle: eine einzeilige Fehlkonfiguration
GitHub lässt Projekte automatisierte Jobs ausführen, wenn jemand eine Änderung vorschlägt. Es gibt zwei Wege, diese Jobs auszulösen, und sie sehen fast identisch aus:
- •Der sichere (
pull_request) führt den vorgeschlagenen Code in einer Sandbox aus, ohne Zugriff auf die Secrets des Projekts.
- •Der gefährliche (
pull_request_target) läuft mit vollem Zugriff auf die Secrets des Projekts, und es ist nur ein einziges Konfigurationswort, das den Unterschied macht.
Das Trivy-Projekt nutzte den gefährlichen Weg so, dass der Code des Contributors mit vollen Rechten lief. Ein Angreifer schlug also einfach eine Änderung mit bösartigem Code vor, und der wurde mit jedem verfügbaren Projekt-Secret ausgeführt. Ein einziger Network Request reichte, um sie alle zu stehlen.
Gestohlen wurde ein langlebiger Access Token, eine Art permanentes Passwort, mit dem man Code über alle Projekte der Organisation pushen kann. Damit konnte der Angreifer in alles schreiben.
Sobald eine Kompromittierung entdeckt wird, ist der erste Reflex, die Credentials zu rotieren. Aber die Reihenfolge ist wichtiger, als die meisten denken.
Der richtige Weg ist eine atomare Rotation. Erst alles sperren, auf Persistenz prüfen und erst dann neue Credentials ausstellen. Behandle die gesamte Organisation als kompromittiert, nicht nur eine einzelne Credential.
Was kompromittiert wurde
Der offensichtlichste Schaden: Bösartige Versionen des Tools wurden in die öffentliche Registry gepusht. Wenn deine Pipeline sie im Angriffszeitfenster heruntergeladen hat, hast du den Code des Angreifers ausgeführt.
Aber es ging tiefer. Die Angreifer schrieben still (per Force Push) 75 der 76 Versionslabels des Tools so um, dass sie auf den bösartigen Code zeigten. Selbst Teams, die eine bestimmte Version "gepinnt" hatten, bekamen die schlechte. Ein Versionslabel ist nur ein verschiebbarer Aufkleber, keine Garantie.
Noch schlimmer: Das eigene, legitime Build-System des Projekts kompilierte und signierte die bösartige Version. Es gab keinen verdächtigen Build zu entdecken, weil die vertrauenswürdige Pipeline die Arbeit des Angreifers erledigte.
Und der eigentliche Gewinn war alles, was danach kam: jedes Secret in jeder Build-Umgebung der Opfer, Cloud Credentials, Access Tokens, SSH Keys, Infrastruktur-Configs. Alles im Zugriff.
Der Diebstahl selbst
Der bösartige Code lief vor dem echten Scanner. Trivy scannte deine Container weiterhin, meldete weiterhin Erfolg. Der Diebstahl passierte still und parallel, in drei Stufen: zuerst ein Durchlauf der Umgebungsvariablen (Cloud Credentials, API Keys für Dienste wie Stripe, Slack und OpenAI), dann ein Durchlauf des Dateisystems (SSH Keys, Cloud-Config-Dateien, Environment Files, sogar die Shell History), dann alles verschlüsselt und rausgeschickt.
Die Verschlüsselung war sauber gemacht, sodass nur ein Key auf den Servern des Angreifers die gestohlenen Daten entsperren kann. Die Lehre für Verteidiger: Sobald deine Credentials das Netz verlassen, sind sie weg. Zurückholen kann man sie nicht.
Exfiltrations-Kanäle
Der Hauptkanal war eine nachgeahmte, per Typosquatting erstellte C2-Domain: scan.aquasecurtiy.org (das "i" fehlt). Im Log leicht zu übersehen, wenn das Auge "aquasecurity" liest.
Der Fallback war raffiniert: Wenn ausgehender Traffic blockiert war, legte die Malware ein öffentliches Repository im GitHub-Konto des Opfers selbst an und lud die verschlüsselte Beute dorthin. GitHub steht bei fast allen auf der Allowlist. Bekannte Bad-Domains zu blockieren stoppt keinen Angreifer, der legitime Infrastruktur als Kurier nutzt.
Angriffsvektoren verändern sich
Über die Angriffe seit März hinweg haben sich vier verschiedene Auslieferungsmechanismen herausgebildet:
- bösartige Install-Scripts, die automatisch laufen, wenn Entwickler ein Paket hinzufügen;
- versteckte Editor-Konfigurationsdateien, die den Stealer jedes Mal neu ausführen, wenn jemand ein Projekt öffnet;
- Verbreitung über Cloud-Infrastruktur, sobald die Credentials in der Hand sind; und
- bösartige Editor-Extensions, die per Auto-Update direkt auf Entwicklermaschinen kommen und Code Review komplett umgehen, der Weg hinter dem GitHub-Breach.
Die Liste bekannter Angriffsvektoren wird nie vollständig sein.
Teil 3: Wie du dich verteidigst
Das Verteidigungsmodell hat drei Schichten: nicht reinlassen, den Schaden begrenzen und beim Deployment durchsetzen.
Schicht 1: Nicht reinlassen
Zeit-Quarantäne. Die meisten bösartigen Paketversionen werden innerhalb von Stunden entdeckt und innerhalb von Tagen entfernt. Wenn dein Update-Bot bei sicherheitskritischen Paketen zwei Wochen wartet, bevor er neue Releases einspielt, erreichen dich die meisten Angriffe nie. Beide großen Update-Bots unterstützen das inzwischen nativ.
IDE-Extension-Sperre. Schalte Auto-Update ab und aktualisiere nach einem bewussten Zeitplan. Extension-Marketplaces haben kein Review-Gate zwischen Veröffentlichung und Auslieferung, und die IDE-Extension hinter dem GitHub-Breach war nur rund 18 Minuten live.
Lifecycle-Scripts deaktivieren. Package Manager erlauben es, die Scripts abzuschalten, die während der Installation automatisch laufen. Das ist der Vektor hinter mehreren dieser Angriffe. Eine Handvoll Pakete braucht sie legitim, die setzt du auf eine Allowlist.
Auto-Merge absichern. Kleine Versionssprünge automatisch zu mergen ist bei den meisten Code-Änderungen in Ordnung. Aber verlange einen menschlichen Blick auf jede Änderung, die Build-Pipelines, Install-Scripts, Base Images oder Konfigurationsdateien von KI-Assistenten berührt.
Ehrliche Grenzen: Nichts davon ist kugelsicher. Manche bösartigen Versionen bleiben wochenlang unentdeckt, und jede Kontrolle schließt nur einige Türen. Hygiene ist die erste Linie, nicht die einzige.
Schicht 2: Den Radius begrenzen
Permanente Credentials abschaffen. Der größte Gewinn bei diesen Angriffen ist ein langlebiger Key, der in einer Build-Umgebung liegt. Moderne Cloud-Plattformen unterstützen Workload Identity Federation. Statt eines permanenten Keys bekommt jeder Build-Job eine temporäre Credential, die belegt "ich bin dieser bestimmte Workflow, auf diesem bestimmten Branch", gültig für eine Stunde. Stiehlt man sie, hat man 60 Minuten schmalen Zugriff statt einem permanenten Schlüssel zum Königreich. Den ursprünglichen Trivy-Einstieg hätte das nicht verhindert, aber es verändert massiv, womit der Angreifer davonkommt.
Ausgehenden Traffic kontrollieren. Build-Maschinen sollten nur die Handvoll Dienste erreichen können, die ein Build wirklich braucht. Das hätte die nachgeahmte Domain blockiert, den GitHub-Fallback aber nicht. Egress-Kontrollen erhöhen die Kosten des Diebstahls, sie beseitigen ihn nicht. Kombiniere sie mit Netzwerk-Logs, die 90 Tage oder länger aufbewahrt werden, denn die erste Frage bei jedem Incident lautet "womit haben unsere Maschinen gesprochen?", und beantworten kannst du das nur, wenn du es geloggt hast.
Logge, was du ausführst. Erfasse jedes Container Image, das deine Systeme ausführen, mit exaktem Fingerprint und Timestamp. Wenn ein Advisory rauskommt, muss "haben wir das ausgeführt?" in Minuten beantwortet sein, nicht in Tagen.
Nutze eine private Registry. Zieh Software nicht direkt aus öffentlichen Registries. Route sie über deinen eigenen Proxy als einzigen Engpass, an dem du Policies durchsetzen kannst.
Schicht 3: Beim Deployment durchsetzen (Binary Authorization)
Hier die unbequeme Frage: Wenn du ein Tool nach Name und Version herunterlädst, was vertraust du eigentlich? Der Registry, dem Publisher und einem Versionslabel, das jeder mit Publish-Zugriff still verschieben kann. Beim Trivy-Angriff bekamen Teams, die bestimmte Versionen gepinnt hatten, trotzdem den bösartigen Code, weil die Labels selbst umgeschrieben wurden.
Der Mindest-Fix: nach Image Digest pinnen. Jede Software hat einen kryptografischen Fingerprint (einen "Digest"), der sich aus ihrem exakten Inhalt ergibt. Ändert sich der Inhalt, ändert sich der Fingerprint, und der Download schlägt fehl. Referenziere Third-Party-Software über den Fingerprint, nicht über das Versionslabel. Update-Bots können das automatisch verwalten.
Der volle Fix: Signaturen an der Tür verlangen. Cloud-Plattformen bieten Admission Control: Produktionssysteme weigern sich, Software auszuführen, die nicht von deiner eigenen Pipeline kryptografisch signiert wurde, nachdem sie deine eigenen Checks bestanden hat, Vulnerability Scan sauber, aus deinem Repository gebaut, von einem Release Manager freigegeben, was auch immer du festlegst. Ein Angreifer, der eine Dependency kompromittiert, erzeugt ein unsigniertes Image, und ein unsigniertes Image läuft schlicht nicht. Die vorherige Version bedient weiter, die Produktion bleibt unberührt.
Ohne das vertraust du darauf, dass das Richtige deployt wurde. Mit dem setzt du es durch.
Teil 4: Was du mitnimmst
Sieben Dinge, die du dieses Quartal ausliefern solltest
Keins davon ist exotisch. Jedes verringert den Schaden.
- Updates verzögern - bei sicherheitskritischen Paketen 14 Tage warten, bevor du neue Releases einspielst, und Extension-Auto-Update abschalten
- Automatische Install-Scripts deaktivieren - die wenigen Pakete, die sie brauchen, auf eine Allowlist setzen
- Nach Fingerprint pinnen, nicht nach Versionslabel - für alles, was du nicht selbst gebaut hast
- Permanente Credentials in deinen Build-Systemen durch kurzlebige ersetzen
- Signierte Software beim Deployment verlangen
- Ausgehenden Traffic von Build-Maschinen einschränken und loggen – 90 Tage oder länger aufbewahren
- Jedes Image loggen, das du ausführst - damit du "haben wir das ausgeführt?" in Minuten beantworten kannst.
Behandle es als Framework, nicht als Checkliste. Aktualisiere die Karte jedes Mal, wenn ein neuer Vektor auftaucht.
Verifiziere alles, auch deine Verifizierer
Supply-Chain-Angriffe können jeden treffen. Die Regeln, auf die sich die meisten Teams verlassen, also Update-Bots, Versions-Pinning, Code Review, Vulnerability Scanning, wurden alle für eine Welt entworfen, in der die Tools selbst vertrauenswürdig waren. Wenn die Build-Pipeline der Kompromittierungspunkt ist, gelten diese Regeln nicht mehr.
Die gute Nachricht: Der Angriff hat mehrere Phasen, und der Angreifer braucht jede einzelne davon zum Erfolg. Du brauchst nur eine, die scheitert. Das ist die Frage, die du an jede Verteidigung stellst: Welche Phase schließt sie?
Die Liste der Angriffsvektoren wird nie vollständig sein. Vor ein paar Monaten dachte niemand an Konfigurationsdateien von KI-Assistenten als Angriffsfläche. Jetzt sind sie es. Der nächste Vektor wird woanders liegen.
Also bleib bescheiden, bleib geschichtet, und verifiziere alles. Auch deine Verifizierer.


