Forgotten LiteLLM Master Key Opened the Door to a Poisoned PyPI Release
A single secret that was committed to a public repository and never rotated gave an attacker a path all the way into LiteLLM's release pipeline. On 21 October 2026, a malicious LiteLLM 1.107.0 was published to PyPI, with matching Docker Hub and GHCR images. It was quarantined within roughly two hours, but anyone who installed it in that window should treat the host as compromised.
What happened
The chain of events began months earlier:
- 27 May 2026 – A configuration file pushed to a public LiteLLM-owned repository contained the master key for an internal deployment of the project's Agent Platform. The commit was force-pushed over quickly and the exposed keys were flagged for revocation, but the master key itself was never revoked.
- 10 October 2026 – An unknown actor used that still-valid key to get into the Agent Platform and pulled out a GitHub CLI OAuth token the service used to open pull requests. The token was not scoped down and belonged to the GitHub organisation owner, which handed the attacker owner-level access to every repository in the organisation.
- 10 and 12 October – The attacker pushed commits to short-lived branches (named in the
ci-tmp-<hex>pattern), each adding a workflow at.github/workflows/cache.ymlwith the harmless-looking message "ci: bump cache config". The workflows ran on push and the branches were deleted minutes later, leaving almost nothing in the normal commit history. They collected GitHub CLI tokens for two engineers with maintainer rights, plus a long list of other secrets. - 21 October 2026 – The attacker overrode branch protection, pointed the release pipeline at a lookalike repository (
Berri-AI/litellminstead ofBerriAI/litellm), published version 1.107.0 to PyPI and pushed the container images, then deleted production and staging run records. - The release was reported the same day; PyPI quarantined the version and the affected Docker tags (
v1.107.0,latest,main-latest,main-stable) were removed or repointed to clean images.
Releases normally require one authorised engineer to trigger them and a special account tied to a physical device in the office to approve them. That control had been relaxed days earlier so that any two engineers could trigger and approve a release, to speed up bug-fix backports. With two stolen maintainer tokens, the attacker could do both. Notably, holding an owner token, the attacker could have removed the restriction outright; one plausible reading is that they chose not to in order to avoid drawing attention.
What the malicious workflows took
The CI workflows were built to harvest credentials rather than code. The secrets targeted included GitHub tokens, a GitHub App identifier and private signing key, keys for the organisation's Linear workspace, the LiteLLM deployment and Together AI and, in the second run, API keys for Anthropic, OpenAI, AWS Bedrock and Tavily, the token for the project's own secret-scanning service, PostgreSQL and Redis connection details, and a serialised Playwright browser session for Linear. That last item matters: a valid browser storage state can sign in to the associated account without a password and without MFA. Stealing the secret-scanning token also potentially gave the attacker visibility into, or control over, the alerts meant to catch exactly this activity.
LiteLLM says it is revoking every token tied to its internal systems and vendor platforms. It also said its first theory, that the GitHub tokens had leaked from deployment logs, turned out to be wrong.
What the poisoned package does
Version 1.107.0 drops Python startup files (.pth and sitecustomize.py) outside the LiteLLM package directory. Because Python loads these automatically, the malicious code runs whenever the Python interpreter starts in that environment, even if no application ever imports LiteLLM. From there it has two paths:
- Credential stealer – collects developer and AI-tool credentials, cloud and workload secrets, browser data, SSH keys, Git and GitLab tokens, environment variables, and tokens for npm, PyPI, pip, Yarn, Maven, Gradle, Composer, RubyGems and Cargo. The data is encrypted (AES-256-CBC with RSA-OAEP key wrapping) and sent by HTTP POST to a
litellm[.]dev/healthcheckendpoint, a lookalike domain registered on 13 October 2026. - Unix backdoor – a background process that checks in roughly every hour to fetch and run attacker-supplied code. The capability is present in the code, but there is no confirmation that remote execution actually took place.
Because the startup files live outside the application folder, uninstalling or upgrading LiteLLM alone may leave the malicious components in place.
Why it matters
This incident shows how supply-chain attacks are built from small, ordinary weaknesses: a secret pushed by mistake, a revocation that did not happen, an over-privileged token, and a release control loosened for convenience. Each one on its own looks minor. Put together, they let an attacker ship code to everyone who trusts a popular AI gateway. Developer workstations and CI runners, which hold the keys to cloud accounts, package registries and AI providers, are the real prize.
What to do
- Check for 1.107.0. Search lockfiles, virtual environments, container images and CI caches for
litellm==1.107.0and for images pulled from the affected tags on 21 October 2026. - Rebuild, don't just upgrade. On any affected machine or image, look for unexpected
.pthfiles andsitecustomize.pyin site-packages. The safest course is to rebuild the environment or host from a known-good state. - Rotate everything that environment could reach: cloud keys, AI provider API keys, GitHub and GitLab tokens, package registry tokens, SSH keys, database passwords and browser sessions. Assume they were taken.
- Hunt for indicators: outbound traffic to
litellm[.]dev, towebhook[.]site, and from69.48.229[.]143; unexplained hourly Python background processes. - Review your own pipeline hygiene. Scope CI and bot tokens to the minimum they need, revoke leaked secrets immediately (rewriting git history does not revoke anything), keep release approvals tied to hardware-backed accounts, and alert on short-lived branches that add or change workflows.
Secrets committed to repositories and over-permissioned CI workflows are exactly what our AI-assisted code review is designed to surface. It checks source code, configuration and pipeline definitions for hard-coded credentials and risky automation before they become the first step in a chain like this one.
