AI coding · fixes ·
LiteLLM 1.107.0 compromised: what to do right now
As of 24 October 2026. This is a live incident. Check the linked issue before you follow any step, because guidance there may change. This is not professional security advice, and these steps can't guarantee a machine is clean. Follow the LiteLLM maintainers' guidance and your own security team.
If you want the next step, read npm min-release-age: allow one urgent security patch.
LiteLLM 1.107.0 was compromised. The public report is BerriAI/litellm #47826, opened on 21 October 2026 and signed by the Upwind security research team. Its summary says "the litellm==1.107.0 wheels on PyPI contain a credential stealer and a remote-code loader. All 7 wheels are affected." LiteLLM maintainers replied in the same issue, treating it as "SEV-0", and confirmed that "PyPI quarantined 1.107.0" and that "The malicious docker images have been removed."
This is the LiteLLM cleanup. For npm cooldown settings see our guide to npm minimum-release-age with a security-patch exception.
Quick answer: am I affected?
- PyPI: you're affected if
litellm==1.107.0was installed from PyPI. The report lists the sha256 of every affected file in its "Affected" table; compare against that table rather than any copy. - Docker: a follow-up comment in the issue (Docker update) says the
v1.107.0,latest,main-latest, andmain-stabletags oflitellm,litellm-database, andlitellm-non_rootpointed to the infected image for a time, and says to "treat every v1.107.0 image as compromised". The report's status line now says those floating tags "no longer point to the v1.107.0 stealer image". - Source code: the report says "The payload is NOT in the
v1.107.0git tag". - Other versions: a maintainer wrote that "Older versions of LiteLLM are not impacted." The report lists the wheels of 1.106.2 and several earlier releases as "Checked and clean".
Check without starting Python
The report warns: "Any Python start in the affected environment runs cook.pth and sitecustomize.py again, and that includes running pip." So check from the shell only. These commands only list or search files:
# the three files the report says the wheels add to site-packages
find / \( -name cook.pth -o -name cook.py -o -name sitecustomize.py \) 2>/dev/null
# did a lockfile or requirements file ever pin 1.107.0?
grep -n "litellm" uv.lock poetry.lock requirements*.txt 2>/dev/null
# which LiteLLM images are on this machine, with digests
docker image ls --digests | grep -i litellm
Python's own docs say sitecustomize is a standard hook that is "typically created by a system administrator in the site-packages directory", so a match on that name alone isn't proof. A cook.pth or cook.py in site-packages is what the report describes. To match image digests, use the table in the Docker update comment linked above. We don't reprint hashes here, so you always compare against the source.
Clean up in this order
These are the report's "Remediation for users" steps, quoted. It opens with: "Don't start with pip install."
- "From the shell, delete
cook.pth,cook.py,sitecustomize.pyand any matching__pycache__/cook*.pycandsitecustomize*.pycfrom every affected site-packages." - "Kill the detached python daemon (it holds
/tmp/remote_code_loader.lock)." - "Reinstall pinned to
litellm==1.106.2. Rebuilding images and venvs from scratch is better." - "If 1.107.0 was ever installed on a host with outbound internet, assume the exfil succeeded. If the marker file exists, the exfil is confirmed. If it doesn't, that proves nothing: containers and tmp cleanup remove it."
The report names the marker file in its IOCs table. For Docker, the update comment says "the remediation from the original report applies inside the container", and that the simplest fix is to redeploy on v1.106.2.
Rotate keys: what a LiteLLM proxy can reach
Step 5 of the report says to "Rotate everything listed above that the host could reach. In particular:"
- "the instance/task IAM role"
- "every provider key stored in the LiteLLM proxy DB, plus the master and virtual keys"
- "the
DATABASE_URLpassword" - "any secret that was in the environment of any process on the host"
Step 6: "Check CloudTrail for GetCallerIdentity from the instance role around install time, then for use of the role's credentials from outside your infrastructure."
Rotate provider keys on each provider's own key page. For the general steps, see what to do when an AI API key leaks, and to limit damage from any key that does leak, see per-user spend limits for OpenAI and Anthropic.
Pin a known version
The report says: "pin litellm==1.106.2". A maintainer wrote: "please pin your version to 1.106.2 or any explicit version published prior to now." In a requirements file that's:
litellm==1.106.2
Use the same exact pin in pyproject.toml for uv or Poetry, then refresh the lockfile. For Docker, an earlier status line in the report said to "Pin v1.106.2 by digest" instead of using a floating tag such as latest.
Stop the next one: a release-age cooldown
A cooldown tells your installer to skip releases newer than a set age. A maintainer wrote that "The impacted version (v1.107.0) was removed within 3 hours of release." A cooldown is designed to make it less likely that a just-published bad release gets installed. Whether it would have helped you depends on when you installed, so treat it as one layer, not a guarantee.
uv: exclude-newer
The uv settings reference says exclude-newer will "Limit candidate packages to those that were uploaded prior to the given date." It "Accepts RFC 3339 timestamps (e.g., 2006-12-02T02:07:43Z), a "friendly" duration (e.g., 24 hours, 1 week, 30 days), or an ISO 8601 duration (e.g., PT24H, P7D, P30D)."
[tool.uv]
exclude-newer = "7 days"
To let one urgent security fix through, the same page documents exclude-newer-package: "Set a package to false to exempt it from the global exclude-newer constraint entirely." Its example:
[tool.uv]
exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z", markupsafe = false }
pip: --uploaded-prior-to
The pip install docs describe --uploaded-prior-to <datetime_or_duration>: "Only consider packages uploaded prior to the given value." It accepts "a duration in days (e.g., ‘P3D’ for packages uploaded at least 3 days ago)", and is "Only effective when using indexes that provide upload-time metadata." The environment variable is PIP_UPLOADED_PRIOR_TO.
pip install --uploaded-prior-to P7D -r requirements.txt
Neither page says which release added the option, so check that your installed uv or pip lists it before you rely on it.
Prevention, not remediation. A cooldown, and the kit below, do nothing for a machine that already ran 1.107.0. They don't clean up an affected machine and don't rotate keys. Do the steps above first.
FAQ
Is 1.106.2 safe? The report lists the 1.106.2 wheels as "Checked and clean", and both the report and the maintainers point users to 1.106.2. We haven't checked it ourselves.
Was the GitHub source compromised? The report says "The payload is NOT in the v1.107.0 git tag". The Docker update comment says the images were built from commits in a lookalike repository. The maintainers have posted their own write-up of how it happened: LiteLLM's attack chain post.
I only used the Docker image. Am I affected? If you ran a v1.107.0 image, or a floating tag while it pointed to that image, the Docker update comment says to treat it as compromised and apply the same remediation inside the container.
Do I have to rotate keys if the marker file is missing? Yes, if 1.107.0 was installed on a host with outbound internet. The report says a missing marker "proves nothing".
Would a cooldown have stopped this? It's designed to delay new releases, so it depends on the cooldown length and when you installed. We don't claim it would have.
If you want one cooldown policy across tools
Disclosure: this is our own paid product.
The Dependency Cooldown + Emergency-Patch Kit, $12 (plus VAT where applicable), is prevention, not remediation. It doesn't clean up an affected machine. This kit is designed to reduce the chance of installing a just-published bad release. A Node script with no dependencies sets one release-age cooldown from a single --days value across npm, pnpm, Yarn, Bun, uv, Renovate, and Dependabot. cooldown allow adds an exemption for one security fix. For Bun and npm, an exemption covers every version of the package. A cooldown does not detect malware. It was tested against a local mock registry with npm, pnpm, and Bun only, not against real Yarn, uv, Renovate, or Dependabot, and not on Windows or macOS. Requires Node 20 or later.
npm is a trademark of npm, Inc. GitHub and Dependabot are trademarks of GitHub, Inc. pnpm, Yarn, Bun, Renovate, uv, Node.js, and other names belong to their owners. Names are used only to identify products and compatibility. Stack & Ship is not affiliated with or endorsed by any of them.
Sources
Checked 24 Oct 2026: github.com/BerriAI/litellm issue #47826, its comments, and the maintainer status updates in it; docs.litellm.ai/blog/security-incident-oct-21-2026-attack-chain (linked only); docs.astral.sh/uv/reference/settings; pip.pypa.io/en/stable/cli/pip_install; docs.python.org/3/library/site.html.
GitHub is a trademark of GitHub, Inc. LiteLLM, PyPI, Python, pip, uv, Poetry, Docker, AWS, CloudTrail, IAM, OpenAI, Anthropic, Gemini, npm, and Node.js belong to their owners. Other names belong to their owners. Names are used only to identify products and compatibility. Stack & Ship is not affiliated with or endorsed by any of them.