Home/ Blog/ Security news/ Article
Blog · Security news

LiteLLM 1.107.0 Compromised: Poisoned Release Steals Cloud and AI Keys

A poisoned LiteLLM 1.107.0 release on PyPI and Docker stole cloud, AI, and SSH credentials via Python startup hooks. Roll back to 1.106.2 and rotate keys.

Transparent glass crate on a conveyor among opaque crates, interior mechanism visible

The wrong question to ask this week is "did we pull a bad version of LiteLLM." The right one is "did any host of ours start Python after installing LiteLLM 1.107.0 on October 21." The compromised release of LiteLLM, the open-source gateway that routes applications to large language models, did not wait to be imported. It planted startup hooks that execute every time the Python interpreter launches on the machine, whether or not the running process ever touches LiteLLM.

That detail reshapes the whole response. According to Microsoft Threat Intelligence, the poisoned wheel placed three files, cook.pth, cook.py, and sitecustomize.py, outside the normal litellm application directory. Python reads .pth and sitecustomize files at interpreter startup as part of ordinary site initialization, so uninstalling the package or rolling an image tag back leaves them behind. Microsoft is explicit that pulling the package does not amount to recovery.

LiteLLM 1.107.0 exposure window09:48 UTC: Build poisoned. 11:39 UTC: Live on PyPI. 11:46 UTC: Socket flags it. 13:23 UTC: Pulled from PyPI. 14:20 UTC: Docker fixed.LiteLLM 1.107.0 exposure window09:48 UTCBuild poisoned11:39 UTCLive on PyPI11:46 UTCSocket flags it13:23 UTCPulled from PyPI14:20 UTCDocker fixed
All times October 21, 2026 (UTC). Source: Socket forensic timeline.

What was published, and how

On October 21, the LiteLLM release pipeline pushed a tampered v1.107.0 to the Python Package Index and to the project's official container images. As reported by Help Net Security, LiteLLM said the attacker took over three of its engineers' GitHub identities, apparently with stolen GitHub CLI OAuth tokens, then split the work across them: one changed the release pipeline, another signed off on it, and a third wiped the workflow records. The company said it believes initial access traced back to an exposed internal deployment.

Socket, whose scanner flagged the malware, reported the wheel carried a 16-module credential collector and a remote-code loader. The collector swept four buckets of secrets: cloud and orchestration access (the major cloud providers plus Kubernetes, Docker, Vault, and Terraform), developer identity (version-control and package-registry logins, SSH and GPG private keys, and .env files), tokens for AI developer tools, and saved browser credentials. It encrypted the haul and shipped it to a lookalike domain. A second-stage loader read a pointer file hosted on GitHub to fetch follow-on code; by early afternoon UTC that pointer returned an empty body, which blunted the remote-code step.

The window was short. On PyPI the bad wheel was reachable between 11:39 and 13:23 UTC, roughly an hour and three quarters, while the Docker images carried the tampered build until 14:20 UTC. LiteLLM reports roughly 23 million weekly downloads; researchers put the number of downloads of the bad build at about 49,000 before it was pulled. Short is not the same as harmless. A few hours is plenty for an unattended install in a continuous-integration job to hand over every secret that job could read.

Why rolling back is the easy half

Most of the coverage ends at "roll back to 1.106.2." That closes the delivery route and does nothing about the two problems that outlast it. First, the startup files sit outside the package, so a host can keep running the stealer after LiteLLM is gone. Second, any credential the compromised host could read in that window should be assumed captured, and a captured key stays valid until someone rotates it. The install is a delivery event; the credential loss is the incident.

This also widens the blast radius past the people who run the LiteLLM proxy. Because the hooks fire at interpreter startup, every Python process on an affected host is in scope, including cron jobs, build steps, and unrelated services that happen to share the environment. "We do not call LiteLLM from that service" is not a reason to exclude a box that had 1.107.0 installed.

The second poisoning of this pipeline in a year

This is the second time in 2026 that the LiteLLM distribution chain has shipped a poisoned release. In March, malicious LiteLLM packages were part of a wider operation we traced when we covered the TeamPCP campaign and again when CloudSEK mapped its reach across roughly 2,500 organizations. A separate authentication-bypass flaw in LiteLLM's Model Context Protocol support surfaced later. Three distinct security events on one project in a year is a pattern, not luck. An AI gateway sits at a credential chokepoint: it holds provider API keys, its own proxy key table, and usually the cloud identity of the server it runs on. That concentration is what makes it worth poisoning, and it is why this class of tool now deserves the same release-pipeline scrutiny teams already give their build runners.

What recovery actually requires

Treat any host that installed 1.107.0 as credential-compromised, not merely as running a bad package. The order of operations:

  • Pin LiteLLM to 1.106.2, the last release confirmed clean. 1.107.0 is the only poisoned version on PyPI and is now quarantined there; no clean release above it exists yet, so do not jump forward in search of a fix.

  • Find and delete the dropped files, including any copies that landed in site-packages, not just the application directory. The hunt list below has the paths and markers.

  • Rotate every credential the affected host could reach: cloud access keys, Kubernetes and Vault tokens, SSH and GPG keys, API keys for AI providers, and the LiteLLM proxy key table itself. Aikido's researcher advised anyone who installed 1.107.0 to treat their credentials as compromised regardless.

  • Rebuild affected containers from a clean base image rather than re-pulling a tag.

Hunt list: any host that ran LiteLLM 1.107.0 (Oct 21)
# Files dropped by the poisoned wheel (check site-packages copies too)
litellm-1.107.0.data/purelib/cook.pth
litellm-1.107.0.data/purelib/cook.py
litellm-1.107.0.data/purelib/sitecustomize.py
# Host markers
/tmp/.pc_once_72129118c59f5636c0bb
/tmp/remote_code_loader.lock
# Exfiltration endpoint and remote-code pointer (defanged)
www[.]litellm[.]dev/healthcheck
raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt
# ATT&CK: T1546.018 Python startup hooks, T1195.001 compromise software dependencies

Microsoft published detection signatures for the payload (Defender flags it under names including Trojan:PyPI/Stealer.SA and a LiteLlmSupplyChain family). Two behavioral observables are worth an alert whether or not you run LiteLLM: a Python process reading SSH keys or cloud instance metadata it has never read before, and an outbound POST from a build or proxy host to the lookalike exfiltration domain. Because the hooks run at any Python start, the detection logic does not depend on the package being present.

The durable lesson is the one the version bump hides. A dependency you trust can turn hostile for a few hours through nothing more than a stolen developer token, and the damage is measured in rotated keys, not in a changelog entry. Pin the things you install to hashes, give release pipelines the same account-takeover defenses you give production, and assume that "we rolled back" is the start of the response, not the end.

Topics

Frequently asked questions

Which LiteLLM version is compromised and which is safe?

Only LiteLLM 1.107.0 is compromised. It was published to PyPI and official Docker images on October 21, 2026, and is now quarantined on PyPI. The last release confirmed clean is 1.106.2, and no fixed version above 1.107.0 exists yet, so pin to 1.106.2.

I uninstalled LiteLLM 1.107.0. Am I safe now?

No. According to Microsoft, the malicious files were placed outside the LiteLLM directory and run at Python startup, so removing the package does not remove them. You must delete the dropped files and rotate every credential the host could read, because captured keys stay valid until changed.

What did the LiteLLM malware steal?

Socket reported a 16-module collector targeting cloud and deployment secrets (AWS, Azure, Google Cloud, Kubernetes, Docker, Vault, Terraform), developer credentials (Git, npm, PyPI, SSH and GPG keys, .env files), AI tool credentials, and browser databases. It encrypted the data and posted it to a lookalike domain.

How was the LiteLLM release pipeline compromised?

LiteLLM said the attacker worked through the GitHub accounts of three engineers using what appear to be stolen GitHub CLI OAuth tokens, as reported by Help Net Security. One account changed the pipeline, a second approved it, and a third deleted the records. Initial access is believed to trace to an exposed internal deployment.

Am I affected if I never import LiteLLM in my code?

Possibly. The stealer installs Python startup hooks that fire whenever the interpreter launches, not only when LiteLLM is imported. Any Python process on a host that installed 1.107.0, including cron jobs and build steps, could have run it, so treat the whole host as exposed.

How many people downloaded the malicious version?

LiteLLM reports roughly 23 million weekly downloads overall. Researchers estimate the tampered 1.107.0 build drew about 49,000 downloads during its window, which ran from 11:39 to 13:23 UTC on PyPI and until 14:20 UTC on Docker Hub on October 21, 2026.

See what Suriq finds on your own servers.

Agentless checks for uptime and your cloud, a lightweight agent for detection on each server, and one console that ranks and explains what it finds.