Schädliches LiteLLM-Paket 1.107.0 auf PyPI entdeckt und entfernt
Eine betrügerische Version von litellm==1.107.0 wurde auf PyPI veröffentlicht, bereits die zweite Kompromittierung des Pakets in diesem Jahr. PyPI hat sie entfernt, sicher ist laut Meldung die Version 1.106.2.

Am 21. Oktober 2026 wurde ein bösartiges litellm==1.107.0 auf PyPI veröffentlicht. Es handelt sich um die zweite Kompromittierung des Pakets in diesem Jahr, unabhängig von dem Vorfall im März. PyPI hat die Version entfernt. Die sichere Version ist 1.106.2.
LiteLLM ist die Bibliothek, die viele Agents und Proxies verwenden, um Claude, GPT und andere Modelle über eine einzige Schnittstelle aufzurufen. Sie gelangt oft als Abhängigkeit ins System, die man nie bewusst installiert hat. Und diese Payload zielt gezielt auf die Zugangsdaten von KI-Coding-Tools ab: Claude, Cursor, Copilot, Gemini CLI, Codex CLI und weitere.
Die bisher beste technische Analyse ist der Beitrag von GMO Flatt Security (auf Japanisch). Dieser Artikel fasst ihn für ein englischsprachiges Publikum zusammen und ergänzt den Teil, den ich sonst nirgends gefunden habe: wie man seinen Installer dazu bringt, ganz neue Releases abzulehnen.
https://blog.flatt.tech/entry/litellm_2nd_compromise
Alle Zeitangaben sind UTC und stammen aus der Timeline von Flatt Security sowie den Release-Metadaten von PyPI.
Die legitimen Versionen 1.107.0rc1 und rc2 waren einige Tage zuvor veröffentlicht worden, sodass 1.107.0 wie das erwartete nächste Release aussah. Wer am 21. Oktober pip install -U litellm ausgeführt hat, ist der wahrscheinlichste Betroffene.
Flatt Security listet 16 Kategorien auf. Diejenigen, die für KI-Entwickler am wichtigsten sind:
Speziell zu Claude Code: Laut der offiziellen Dokumentation liegen die Zugangsdaten unter macOS im macOS Keychain und auf Linux und Windows in ~/.claude/.credentials.json. Unter macOS greift das System auch auf die Datei zurück, wenn der Keychain nicht beschrieben werden kann, etwa über SSH. Wer Claude Code in CI oder auf einem Linux-Rechner betreibt, sollte diese Datei als offengelegt betrachten.
Ich habe diese Prüfungen auf meinem eigenen Mac ausgeführt. Nichts stimmte überein, aber allein pip show hätte mir das nicht verraten.
1. Finden Sie jede installierte Kopie. pip show prüft nur die aktuelle Umgebung. Suchen Sie stattdessen nach dem dist-info-Ordner, der die Version im Namen trägt und auch Kopien in uv tool- und pipx-Umgebungen findet.
find ~ -maxdepth 8 -type d -iname 'litellm-*.dist-info' 2>/dev/null Enter fullscreen mode Exit fullscreen mode litellm-1.107.0.dist-info bedeutet, dass diese Umgebung infiziert ist.
2. Prüfen Sie Lockfiles. Eine fixierte 1.107.0 wird jeden erneut infizieren, der die Umgebung aus einem internen Mirror oder Cache neu aufbaut.
grep -rIl -i 'litellm' --include = 'requirements*.txt' --include = 'pyproject.toml' \ --include = 'uv.lock' --include = 'poetry.lock' ~/code 2>/dev/null Enter fullscreen mode Exit fullscreen mode 3. Suchen Sie nach den Markern.
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>&1 ps aux | grep -E 'cook|remote_code_loader' | grep -v grep Enter fullscreen mode Exit fullscreen mode Die erste Datei bedeutet, dass die Daten bereits gesendet wurden. Die Lock-Datei oder ein passender Prozess bedeutet, dass die Hintertür läuft. Unter macOS wird /tmp beim Neustart geleert, also ist ein fehlender Marker allein kein Beweis für Sicherheit. Kombinieren Sie das mit Schritt 1.
4. Wenn Sie betroffen sind, folgen Sie den Entfernungs-Schritten von Flatt Security und rotieren Sie anschließend alles so, als wäre es gestohlen worden. Die KI-spezifischen Punkte, die leicht vergessen werden:
Prüfen Sie zusätzlich auf der Nutzungsseite jedes Anbieters den Datenverkehr seit dem 21. Oktober, den Sie nicht zuordnen können.
Das bösartige Release war weniger als einen Tag lang verfügbar. Wer Releases ablehnt, die erst wenige Stunden alt sind, wäre vollständig an ihm vorbeigekommen. Der eigene Registry-Proxy von Flatt Security wendet eine dreitägige Quarantäne an, und dessen Nutzer waren nicht betroffen. Denselben Effekt können Sie mit Funktionen erreichen, die bereits in uv und pip eingebaut sind.
uv: exclude-newer akzeptiert eine Dauer wie 24 hours, 1 week oder 3 days oder eine ISO-8601-Dauer wie P3D. Sie wird mit der Upload-Zeit jeder Datei verglichen.
# pyproject.toml [ tool. uv ] exclude-newer = "3 days" Enter fullscreen mode Exit fullscreen mode In einer globalen ~/.config/uv/uv.toml lassen Sie die Zeile [tool.uv] weg und behalten exclude-newer = "3 days" bei.
pip: --uploaded-prior-to akzeptiert eine Dauer in Tagen im P3D-Format. Es funktioniert nur mit Indexes, die Upload-Zeiten bereitstellen, was bei PyPI der Fall ist.
pip install --uploaded-prior-to P3D litellm # oder als Standard setzen export PIP_UPLOADED_PRIOR_TO = P3D Enter fullscreen mode Exit fullscreen mode Wenn Ihr pip die Option nicht erkennt, aktualisieren Sie pip.
Der Haken sind dringende Fixes. Wenn eine Bibliothek einen Sicherheitsfix am selben Tag ausliefert, können Sie nicht drei Tage warten. uv erlaubt es, einzelne Pakete mit exclude-newer-package auszunehmen:
[ tool. uv ] exclude-newer = "3 days" exclude-newer-package = { cryptography = false } Enter fullscreen mode Exit fullscreen mode Bei pip deaktivieren Sie die Variable für diese eine Installation. "Standardmäßig warten, bewusst ausnehmen" hinterlässt eine Spur in Ihrer Shell-History oder im Commit, wenn Sie die Verzögerung überspringen.
Für Node.js bietet pnpm eine Einstellung für denselben Zweck, minimumReleaseAge ( https://pnpm.io/settings ).
Wer Claude Agents auf Claude Managed Agents betreibt: Vault-Zugangsdaten vom Typ environment_variable liegen im Sandbox-Bereich nur als opake Platzhalter vor und werden beim Ausgang gegen das echte Secret getauscht, sodass eine vergiftete Abhängigkeit, die Umgebungsvariablen ausliest, den Platzhalter statt des Schlüssels erhält: https://platform.claude.com/docs/en/managed-agents/vaults
Ich schreibe über Claude-API-Änderungen, sobald sie ausgeliefert werden. Die englische Ausgabe meines Claude 5 Migration Guide ist auf Gumroad erhältlich: https://persimmoq.gumroad.com/l/claude-5-migration-guide
Automatisch übersetzt. Das Original auf Englisch ist unten aufklappbar.
Original (Englisch) anzeigen
On October 21, 2026, a malicious litellm==1.107.0 was published to PyPI. It is the second compromise of the package this year, separate from the one in March. PyPI has removed it. The safe version is 1.106.2.
LiteLLM is the library many agents and proxies use to call Claude, GPT and other models through one interface. It often arrives as a dependency you never installed on purpose. And this payload goes after AI coding tool credentials by name: Claude, Cursor, Copilot, Gemini CLI, Codex CLI and others.
The best technical analysis so far is the write-up by GMO Flatt Security (in Japanese). This post summarizes it for an English-speaking audience and adds the part I couldn't find elsewhere: how to make your installer refuse brand-new releases.
https://blog.flatt.tech/entry/litellm_2nd_compromise
Times are UTC, from Flatt Security's timeline and PyPI's release metadata.
The legitimate 1.107.0rc1 and rc2 had been published days earlier, so 1.107.0 looked like the expected next release. Anyone who ran pip install -U litellm on October 21 is the most likely victim.
Flatt Security lists 16 categories. The ones AI developers should care about most:
On Claude Code specifically: per the official docs, credentials live in the macOS Keychain on macOS and in ~/.claude/.credentials.json on Linux and Windows. macOS also falls back to the file when the Keychain can't be written, for example over SSH. If you run Claude Code in CI or on a Linux box, treat that file as exposed.
I ran these on my own Mac. Nothing matched, but pip show alone would not have told me that.
1. Find every installed copy. pip show only checks the current environment. Search for the dist-info folder instead, which carries the version in its name and also catches copies inside uv tool and pipx environments.
find ~ -maxdepth 8 -type d -iname 'litellm-*.dist-info' 2>/dev/null Enter fullscreen mode Exit fullscreen mode litellm-1.107.0.dist-info means that environment is infected.
2. Check lockfiles. A pinned 1.107.0 will reinfect whoever rebuilds the environment from an internal mirror or cache.
grep -rIl -i 'litellm' --include = 'requirements*.txt' --include = 'pyproject.toml' \ --include = 'uv.lock' --include = 'poetry.lock' ~/code 2>/dev/null Enter fullscreen mode Exit fullscreen mode 3. Look for the markers.
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>&1 ps aux | grep -E 'cook|remote_code_loader' | grep -v grep Enter fullscreen mode Exit fullscreen mode The first file means the data has already been sent. The lock file or a matching process means the backdoor is running. On macOS /tmp is cleared on reboot, so a missing marker is not proof of safety on its own. Combine it with step 1.
4. If you were hit, follow Flatt Security's removal steps, then rotate everything as if it was stolen. The AI-specific items people forget:
Also check each provider's usage page for traffic since October 21 that you don't recognize.
The malicious release was live for less than a day. Refusing releases that are only hours old would have skipped it entirely. Flatt Security's own registry proxy applies a 3-day quarantine, and its users were not affected. You can get the same effect with features already built into uv and pip.
uv: exclude-newer accepts a duration such as 24 hours, 1 week or 3 days, or an ISO 8601 duration such as P3D. It is compared against each file's upload time.
# pyproject.toml [ tool. uv ] exclude-newer = "3 days" Enter fullscreen mode Exit fullscreen mode In a global ~/.config/uv/uv.toml, drop the [tool.uv] line and keep exclude-newer = "3 days".
pip: --uploaded-prior-to accepts a duration in days in the P3D form. It only works with indexes that expose upload times, which PyPI does.
pip install --uploaded-prior-to P3D litellm # or make it the default export PIP_UPLOADED_PRIOR_TO = P3D Enter fullscreen mode Exit fullscreen mode If your pip doesn't recognize the option, upgrade pip.
The catch is urgent fixes. When a library ships a same-day security fix, you can't wait three days. uv lets you exempt single packages with exclude-newer-package:
[ tool. uv ] exclude-newer = "3 days" exclude-newer-package = { cryptography = false } Enter fullscreen mode Exit fullscreen mode With pip, unset the variable for that one install. "Wait by default, opt out on purpose" leaves a trace in your shell history or commit when you skip the delay.
For Node.js, pnpm has a setting for the same purpose, minimumReleaseAge ( https://pnpm.io/settings ).
If you run Claude agents on Claude Managed Agents, vault credentials of type environment_variable sit in the sandbox only as opaque placeholders and are swapped for the real secret at egress, so a poisoned dependency that dumps environment variables gets the placeholder, not the key: https://platform.claude.com/docs/en/managed-agents/vaults
I write about Claude API changes as they ship. The English edition of my Claude 5 migration guide is on Gumroad: https://persimmoq.gumroad.com/l/claude-5-migration-guide