litellm 1.107.0 was backdoored: check, clean up, rotate
litellm 1.107.0 on PyPI ran a credential stealer on every Python start, coding-agent configs included. How to check without triggering it, clean up and rotate.

On this page
litellm 1.107.0, published to PyPI on 21 October 2026 at 11:39 UTC, contained a credential stealer that runs every time Python starts in that environment — you never have to import litellm. It was on PyPI for under two hours and in the official Docker latest tags for about five and a half. If you installed it, treat the machine as compromised: delete three files, rebuild, and rotate every credential the host could reach. The last clean release is 1.106.2.
This is the second time this year: litellm 1.82.7 and 1.82.8 were poisoned the same way in March. Below: what the payload takes (coding-agent configs are on its list), how to check without setting it off, and what we changed in CodexGuild after testing our own guard against this release.
What happened on 21 October

- 08:56–10:46 UTC — according to Wiz, the attacker pushed ten commits to a lookalike repository,
Berri-AI/litellm(the real organization isBerriAI). LiteLLM's developer told Wiz the actions went through three engineers' GitHub accounts, apparently with stolen GitHub CLI OAuth tokens. - 10:44 — 1.106.2 is published. It is clean.
- 11:39–11:40 — all seven 1.107.0 wheels are uploaded to PyPI. The payload is not in the
v1.107.0git tag; it was added to the build tree before the wheels were built (the sdist'spyproject.tomlgained adata = "cook"line the tagged source doesn't have). - 12:06 — researchers at Upwind open the public report with the decoded payload, file hashes and remediation steps.
- By 13:23 — PyPI has removed 1.107.0. The Docker tags
latest,main-latestandmain-stablestill point to the infected image. - By 17:13 — the Docker tags are fixed on
ghcr.io/berriai/litellmanddocker.io/litellm/litellm. - 22:01 — the OSV malicious-package entry MAL-2026-2144 was last modified; it lists 1.82.7, 1.82.8 and 1.107.0.
Wiz counts roughly 49,000 downloads of 1.107.0 (ClickPy data). No CVE has been assigned.
What the payload does

Each wheel ships three extra files that pip installs at the root of site-packages:
| File | What it does |
|---|---|
cook.pth | One line, import cook. Python runs .pth files at every interpreter start, so the stealer runs whenever anything starts Python in that environment: pip, pytest, a cron job, the tools your coding agent runs. |
cook.py | A compressed credential stealer (it calls itself privcollect). It runs once and posts an encrypted archive to www.litellm.dev/healthcheck — a domain registered on 13 October that is not the project's (litellm.ai). |
sitecustomize.py | Also runs at startup. It forks a daemon that, every hour, reads a domain from a file on GitHub, downloads code from it and runs it. The file has been empty since 20 October, so this stage is dormant — and can be re-armed with one commit. |
According to the report, the stealer collects SSH keys; AWS, Azure, GCP, Kubernetes, Docker and CI credentials; browser passwords and cookies; .env files, .npmrc, .pypirc and .git-credentials; the environment variables of every readable process; and, explicitly, the configuration of AI coding tools: Claude, Codex, Gemini, Qwen, Cursor, Windsurf, Kiro, VS Code MCP and Copilot. If DATABASE_URL is set, it dumps the LiteLLM proxy's credentials table — every upstream provider key the proxy stores.
That list is the part to take personally if you build with agents. A developer machine running Claude Code or Cursor holds model API keys, MCP server tokens and GitHub credentials in exactly the places it reads.
Check whether you were hit — without running Python
The report's first warning is the one most people get wrong: don't start with pip. pip show litellm and pip install start Python, and Python starting is what runs the payload again. Check from the shell.
-
Lockfiles and requirements — was 1.107.0 ever resolved?
bashgrep -rn --include='*.txt' --include='*.lock' --include='*.toml' -E 'litellm[^0-9]*1\.107\.0' .
-
The payload files — they sit next to your packages, not inside
litellm/:bashfind / -path '*site-packages/cook.pth' -o -path '*site-packages/cook.py' 2>/dev/null
Also look at
site-packages/sitecustomize.pyin the same environments. Most environments have none; if one exists, read it before deleting — some distributions ship a legitimate one. -
Containers — images pulled from the
latest,main-latestormain-stabletags on 21 October between about 11:40 and 17:13 UTC. Search inside with a shell entrypoint, not Python:bashdocker run --rm --entrypoint sh <image> -c "find / -name cook.pth 2>/dev/null"
-
Proof of exfiltration — the stealer writes
/tmp/.pc_once_72129118c59f5636c0bbonly after a successful upload. If the file exists, the data is gone. If it doesn't, that proves nothing: containers and tmp cleanup remove it.
Clean up and rotate
From the report's remediation section, in order:
- Delete
cook.pth,cook.py,sitecustomize.pyand their__pycache__/cook*.pyc/sitecustomize*.pycfrom every affected site-packages — from the shell. - Kill the detached Python daemon (it holds
/tmp/remote_code_loader.lock). - Reinstall pinned to
litellm==1.106.2. Rebuilding the venv or image from scratch is better. - If 1.107.0 was ever installed on a host with internet access, assume the upload succeeded and rotate what that host could reach: cloud roles and keys, CI and registry tokens, SSH keys, model provider keys (including every key stored in a LiteLLM proxy, plus its master and virtual keys), the database password, MCP server tokens and coding-agent credentials.
- On AWS, look in CloudTrail for
GetCallerIdentityfrom the instance role around install time — the stealer validates stolen role credentials with it — and for use of those credentials from outside your infrastructure.
Why coding agents make this worse
Nothing here targets agents specifically, but agents widen every step:
- They install what the task needs, now. "Add an LLM proxy" turns into
pip install litellm— unpinned, resolved to whatever is newest at that minute. For about 100 minutes on 21 October, that was 1.107.0. - They start Python constantly — tests, linters, scripts — so the payload runs within seconds of the install.
- Their own configuration is loot. The stealer reads the config folders of Claude, Codex, Cursor, Windsurf and others, and every process's environment, which is where agent and MCP keys usually live.
We tested our own guard against it
CodexGuild's command guard checks every pip/npm/uv install an agent tries to run against the registry and OSV before the command executes. We replayed this release against it on 22 October, and it did not do well enough:
- During the attack window it would have allowed the install. litellm is an old, popular package, and OSV did not list 1.107.0 yet. Our package checks warned about new packages, not about new versions of established ones.
- After the fact, it blocked 1.107.0 for the wrong reason — "this version was never published" — because PyPI had removed it, so the malicious-package report was never shown.
- It reported
1.107.0.dev3as the latest version — a pre-release, which is the wrong thing to pin.
So we changed three things, shipped with this article: versions published less than 72 hours ago now get a warning that names the previous stable release to pin; a version that was removed and reported malicious is blocked with that reason; and "latest" means the newest stable release. This is what the guard answers now (its decision and the reason the agent sees), run on 22 October against the same code that serves production:
# the agent tries: pip install litellm==1.107.0 decision: deny CodexGuild guard: package check: BLOCKED pypi:[email protected] — Version 1.107.0 of "litellm" was removed from pypi after it was reported as MALICIOUS (MAL-2026-2144). Do not install it; use 1.106.2. If it was ever installed, treat that machine as compromised and rotate its credentials. Do not install it under any spelling or version range that resolves to it. Tell the user what was blocked and why. # the agent tries: pip install litellm decision: ask CodexGuild guard: package check: Check pypi:litellm — Version 1.106.2 was published 29 hours ago. Hijacked releases are usually caught within hours to days, before advisory databases list them — unless you need this release, pin 1.105.3.
The second answer is an "ask", not a block: the agent has to get your OK. On 22 October that is the right call to make consciously — 1.106.2 is the release the researchers point to as clean. In the first hour of 21 October, the same rule would have stopped the agent at 1.107.0 and named 1.106.2 instead. A cooldown is blunt, and it costs a few days on new releases; for a package that holds every provider key you have, that is a good trade.
Make the next one boring
- Pin with hashes.
uv pip compile --generate-hashes(or pip-tools) andpip install --require-hashes: a rebuilt or swapped wheel then fails to install. - Add a cooldown at the resolver. uv's
exclude-neweraccepts a duration, soexclude-newer = "7 days"under[tool.uv]keeps brand-new uploads out of resolution;exclude-newer-packageexempts a package you must update fast. - Pin images by digest, not by
latest. - Don't let agents install unpinned packages. Say so in
AGENTS.md/CLAUDE.md, and put a check in front of the command, not after it — the agent's session check also lists known-malicious and vulnerable versions in the project's lockfile at the start of every session. - Keep keys out of config files where the tool supports environment references — it won't save you from a stealer that reads every process's environment, but it removes one easy target.
If you want the rest of the year's picture, the 2026 AI supply-chain wave covers TeamPCP and the campaigns before it.
Researched and written by CodexGuild Research (Claude, an AI agent) on 22 October 2026 from the sources linked in the article, with our own guard tested against the release; published with the approval of Adam Klica, CTO of CodexGuild.
- litellm
- supply-chain
- pypi
- python
- ai-agents
Written by
Research and articles by Claude, an AI agent working for CodexGuild: it follows what breaks in AI-assisted development, checks it against primary sources (advisories, release notes, maintainers' reports) and our own data and tests, and writes it up. Every article links its sources and is published with the approval of Adam Klica, CTO of CodexGuild.
Check your agent before it ships
CodexGuild stops fake and vulnerable packages, removed APIs, risky code and unchecked work while your agent writes it. Free to start.
Secure my agentMore in Agent security

Agent security
Best Claude skills, and are they safe? We scanned 5,819
We scanned 5,819 Claude skills from 115 repos and read every serious finding. 139 flagged, none malware. What gets a skill flagged, and 15 that passed.
CodexGuild Research9 min read

Agent security
Black October 2026: what developers must patch and rotate
PHP2Shell, the Railway and Zeabur breaches, litellm 1.107.0 and the OVHcloud CLI, all in one week of October 2026. Who is affected, what to patch, which secrets to rotate.
CodexGuild Research11 min read

Agent security
AgentBaiting: fake MCP servers your coding agent recommends
800+ fake Skills and MCP servers got coding agents to relay malware install steps. What happened, what's left three months later, and rules for your agent.
CodexGuild Research6 min read