Alle Beiträge

Ein Paket, alle Schlüssel: das kompromittierte LiteLLM-Release

Sicherheit · 4 Min. Lesezeit ·

Ich schreibe PHP und Node, und das hier ist ein Python-Vorfall. Ich schreibe trotzdem darüber, weil das Muster nichts mit der Sprache zu tun hat: Eine Bibliothek, die vor all deinen KI-Providern sitzt, hält auch alle deren Schlüssel, und ein einziges vergiftetes Release erreicht damit jeden davon. Laut dem Incident-Tracker pwn.watch ist genau das LiteLLM am 21. Oktober 2026 passiert.

Was der Tracker meldet

Das Folgende ist die Zusammenfassung des Trackers, also die Darstellung eines einzelnen Aggregators; bevor du handelst, prüfe das offizielle Advisory des Projekts. Der Tracker stuft den Eintrag als kritisch ein und führt ihn als behoben. Demnach haben Angreifer die Release-Pipeline von LiteLLM kompromittiert und ein bösartiges litellm==1.107.0 auf PyPI veröffentlicht, das etwa zwei Stunden online war, dazu kompromittierte Tags auf Docker Hub und GHCR: v1.107.0, latest, main-latest und main-stable. Laut Tracker legen die Wheels cook.pth, cook.py und sitecustomize.py ab, die bei jedem Python-Start Cloud-, Entwickler- und KI-Tool-Zugangsdaten stehlen und einen Loader für entfernten Code öffnen. Der Tracker nennt es die zweite Kompromittierung von LiteLLM im Jahr 2026.

Der Tag latest verdient einen zweiten Blick. Ein Container, der beim Neustart latest zieht, brauchte kein manuelles Upgrade, um das abzubekommen.

Ein Einzelfall ist es womöglich auch nicht. Railway schreibt in seiner eigenen Offenlegung vom selben Tag, man gehe davon aus, dass der eigene Vorfall Teil einer Angriffsserie auf Plattformanbieter sei, die auf KI-Inferenz-Provider abzielt.

Warum ein KI-Gateway das Ziel ist

Allgemeinwissen: Eine Gateway- oder Proxy-Bibliothek gibt es, damit deine Anwendung über eine einzige Schnittstelle mit vielen Modell-Providern spricht. Der Prozess, der sie ausführt, hat also alle Provider-Schlüssel gleichzeitig in seiner Umgebung. Eine gewöhnliche kompromittierte Abhängigkeit erbeutet die Schlüssel eines Dienstes. Diese hier erbeutet die Schlüssel aller, und KI-Schlüssel sind Budget, das jemand anderes verbrauchen kann.

Vergiftetes Release Gateway-Prozess alle Schlüssel im Env Schlüssel Provider A Schlüssel Provider B Cloud-Zugänge ein Release, alle Schlüssel
Der Schadensradius eines Gateways ist jedes Geheimnis, das man ihm gegeben hat, nicht ein einzelner Dienst.

Die Startdateien machen es schlimmer. Ebenfalls Allgemeinwissen und dokumentiertes Python-Verhalten: .pth-Dateien in site-packages werden beim Start des Interpreters verarbeitet, und Zeilen darin, die mit import beginnen, werden ausgeführt; auch sitecustomize läuft beim Start. Ein bösartiges Wheel dieser Art wartet also nicht darauf, dass dein Code die Bibliothek importiert. Jeder Python-Prozess in dieser Umgebung führt es aus, auch ein einmaliges Skript oder ein Testlauf.

Für PHP- und Node-Leser gilt dieselbe Form für alles, was viele Zugangsdaten hält: einen Wrapper um Stripe, Twilio oder mehrere KI-SDKs, oder ein Deployment-CLI mit Zugriff auf jede Umgebung.

Eindämmung, die den Schaden begrenzt

Nichts davon verhindert, dass eine Pipeline kompromittiert wird. Es begrenzt, was ein einzelnes schlechtes Release erreichen kann.

1. gepinnte Version und Hash bestimmen, was hineinkommt 2. isolierter Container, nur die eigenen Secrets Gateway- Bibliothek 3. Enge Schlüssel, kurzlebig, gedeckelt
Jede Schicht verkleinert, was ein vergiftetes Release erreicht, selbst wenn es installiert wird.

Nach Version und Hash pinnen. Eine Versionsnummer allein stoppt keine neu veröffentlichte oder ausgetauschte Datei; ein Hash schon. Mit pip lehnt eine Requirements-Datei mit Hashes zusammen mit --require-hashes alles andere ab; die Lockfiles von uv und pip-tools erledigen dieselbe Aufgabe. Pinne Container-Images per Digest statt über einen wandernden Tag wie latest, und warte ein paar Tage, bevor du ein brandneues Release übernehmen. Isolieren. Installiere und betreibe das Gateway in einer eigenen Umgebung oder einem eigenen Container, der nur die nötigen Schlüssel hält, und installiere nie neue Pakete auf einer Maschine, auf der Produktions-Secrets geladen sind. Schlüssel eingrenzen. Gib jedem Provider einen eigenen, kurzlebigen Schlüssel mit Ausgabelimit, damit ein gestohlener billig ist und schnell ersetzt wird.

pip install --require-hashes -r requirements.txt
pip show litellm
Behandle jede Bibliothek, die mehrere Provider-Schlüssel hält, als die sensibelste Abhängigkeit, die du hast: per Hash pinnen, allein betreiben und mit Schlüsseln ausstatten, die ablaufen.

Falls 1.107.0 installiert oder gezogen wurde

Grobe Reihenfolge: Nimm die Umgebung oder den Container vom Netz, prüfe, welche Version und welcher Image-Tag tatsächlich lief, baue aus einem bekannt sauberen, gepinnten Release neu, und rotiere von einer sauberen Maschine aus jeden Schlüssel, den diese Umgebung lesen konnte. Wegen der Startdateien zählt jeder Python-Prozess dort, nicht nur das Gateway. Prüfe die betroffenen Versionen und Tags im offiziellen Advisory von LiteLLM.

Quelle: der Incident-Tracker pwn.watch, Eintrag „LiteLLM 1.107.0 PyPI/Docker supply-chain compromise“.

Notizen der Leser

  1. Noch keine Notizen. Die erste ist immer die mutigste.
Baust du etwas Ähnliches? Ich kann helfen. Schreib mir auf WhatsApp