WEDNESDAY, OCTOBER 21, 2026|No. 19563
Cybersecurity · Supply Chain

LiteLLM Package Compromised on PyPI with Malicious Payload

The PyPI repository has removed version 1.107.0 of the LiteLLM library after security researchers discovered it contained a credential stealer and a remote backdoor.

The PyPI repository logo represents the central hub for Python software distribution.
The PyPI repository logo represents the central hub for Python software distribution. · Photo by FlyD on Unsplash
1 sources
Pipeline ingest
3 reads
Positive / Neutral / Negative
0 countries
Related coverage

Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor

The LiteLLM 1.107.0 release on PyPI carries a credential stealer and a remote code execution backdoor. All seven wheels (Linux, macOS, Windows) install them as three files in site-packages. Both run when any Python process starts on the host, even one that never imports litellm. The upstream GitHub source does not contain them. PyPI has since removed the release.

Versions 1.106.2, 1.107.0rc1, and 1.107.0rc2 are clean. The companion packages that 1.107.0 pins, litellm-proxy-extras==0.4.110 and litellm-enterprise==0.1.78, are also clean.

What the attack does

Installing litellm==1.107.0 places three files in site-packages. Python loads two of them each time it starts.

  1. cook.pth imports cook.py, a credential stealer. It collects SSH keys, cloud credentials, CI/CD secrets, AI tool tokens, browser passwords, and the LLM provider keys in a LiteLLM proxy database. It encrypts the data and sends it to www.litellm[.]dev.
  2. sitecustomize.py starts a background daemon. Every hour, the daemon reads a server address from a GitHub file, runs the stealer again, and downloads and runs code from that server.

How the implant got into the release

The pyproject.toml in the 1.107.0 source distribution (sdist) has one extra line in the maturin build section:

The maturin data = "cook" setting copies a cook/ folder into litellm-1.107.0.data/purelib/ in the wheel. pip installs that folder into site-packages.

The sdist leaves out the cook/ folder, so this line is the only visible change. No public commit in BerriAI/litellm contains data = "cook" or a cook/ folder.

The release does not match its tag

The tag v1.107.0 points to commit 66c8f5b. Its pyproject.toml says version = "1.108.0". SafeDep compared every sdist file with the git trees by blob hash. The sdist matches a later main commit, a8113b0, plus five edited files and the cook/ folder.

How the wheels were built

The malicious wheels match the output of the normal BerriAI release pipeline. SafeDep assesses, with moderate to high confidence, that BerriAI’s private release pipeline built these wheels from an attacker-modified git source. The attacker could have used a compromised maintainer or bot credential, a private branch or mirror, or the reference the pipeline builds from.

Payload 1: the credential stealer in cook.py

At startup, Python runs each line that starts with import in a .pth file in site-packages. cook.pth contains import cook, so the stealer runs in every Python process on the host: the application, pip, IDE language servers, and CI jobs.

What it collects

The stealer targets system information, browser passwords and history, SSH keys, shell history, cloud credentials (AWS, Azure, GCP, Kubernetes, Docker), developer secrets, CI/CD secrets, AI development tool tokens, environment variables, LiteLLM proxy database credentials, and GPG/TLS keys.

How it sends the data

  1. It encrypts the JSON results with a random AES-256-CBC key, and encrypts that key with RSA-OAEP and the embedded public key.
  2. It packs the result into a tar.gz and sends it in a POST request to www.litellm[.]dev/healthcheck with the header X-Token: XWiA8gZNa7NcX2XRoAEb.
  3. After a successful upload, it writes a marker file to ensure it collects only once per host.

Payload 2: the backdoor in sitecustomize.py

Python imports sitecustomize at startup, so this file also runs in every Python process. It forks a background daemon that reads a domain from a GitHub repository, runs the stealer, and executes downloaded code from the attacker's server.

PAN's pipeline reviewed approximately 1 open sources for this article. No human editor reviewed this article before publication.

Related Reads

Show on timeline →

Earlier on PAN

More in Technology →