Malicious releaseLiteLLM 1.107.0PyPI and Docker

LiteLLM Supply Chain Attack. Find It. Rebuild. Rotate.

LiteLLM 1.107.0 on PyPI and Docker shipped a credential stealer and a remote code loader. Clear steps to find every affected host, and a reactive hunt to scope the damage across your estate or your clients'.

At a Glance

Facts from BerriAI's incident updates, PyPI and independent researcher analysis. Last updated 22 October 2026, 00:00 BST.

13 Oct

Lookalike domain litellm[.]dev and the dead drop GitHub account are registered.

21 Oct, 12:39 BST

All seven malicious 1.107.0 wheels are uploaded to PyPI.

21 Oct, 12:46 BST

Infected images are published. Tags v1.107.0, latest, main-latest and main-stable point to them on Docker Hub and GHCR.

21 Oct, 14:23 BST

PyPI has removed 1.107.0. Unpinned pip installs from 12:39 to 14:23 BST may have pulled it.

21 Oct, 14:51 BST

The affected GHCR tags are unavailable. Docker Hub tags still point to the infected image.

21 Oct, about 15:20 BST

All affected Docker Hub tags are removed or repointed to clean images. BerriAI says stolen GitHub CLI OAuth tokens from three engineers were used to publish the release.

Now

Find every install, rebuild those hosts, rotate credentials and block the attacker infrastructure.

What to Do in the Next 24 Hours

Proactive on the left. Reactive on the right. Tick both tracks.

Proactive: Find LiteLLM 1.107.0

Do not start with pip or Python on a suspect host. Any Python start there runs the malware again. Use the shell and your tooling instead.

Free Checker Scripts

Tested by the CybaVerse threat hunt team. Run them on developer laptops, CI runners, servers and LiteLLM proxy hosts to get a clear verdict, whether you look after your own business or your clients' estates.

Read-only by design

Both scripts read files and process information only. They never start Python or pip on the host, because that would run the malware again. They read package METADATA and RECORD files directly instead. The only other commands they run are read commands such as docker images, docker image inspect, a docker exec directory listing inside running containers (Linux script), and journalctl. Nothing is written, deleted or killed. Review any script before you run it.

Verdicts

  • CLEANNothing found. A clean result is not proof, because containers and /tmp cleanup remove markers.
  • COMPROMISED1.107.0 is installed, payload files, a marker or lock file, a loader process, a matching image, or DNS or log traces of litellm[.]dev were found.
  • UNKNOWNNeeds review: for example a cook.py with a different hash, a floating LiteLLM image built on 21 October, or a suspicious Python command line.
  • REFERENCED_ONLY1.107.0 is referenced in a lockfile, manifest or cache but is not installed on this host. Check every machine or CI job that used those files.

Exit codes

CodeMeaning
0CLEAN
1COMPROMISED
2UNKNOWN, needs review
3REFERENCED_ONLY

MSPs and internal IT teams can use the exit code in RMM or deployment tooling to flag hosts at scale.

Know the limits

  • Only the prefixes of the litellm-database and litellm-non_root image digests have been published, so the scripts match on those prefixes.
  • Images that are not running are not unpacked, because that would mean creating containers. A floating-tag image is flagged UNKNOWN by its build date only.
  • On Windows the loader can't fork and the /tmp marker doesn't exist, so marker checks rarely fire, and process environment variables can't be read. Linux DNS caches are not inspected, so use resolver, proxy or EDR logs.
  • Removed hosts, short-lived CI runners and rebuilt containers leave no local traces. Check CI logs and lockfile history for installs from 12:39 to 14:23 BST on 21 October, and image pulls from 12:46 to about 15:20 BST.

Reactive: How to Hunt

Assume any host that installed 1.107.0 sent its secrets to the attacker. Hunt to scope the damage, then rebuild and rotate. CybaOps can run these hunts across your estate or your clients'.

Indicators of compromise

Confirmed by LiteLLM's incident post (image digests), PyPI and independent analysis by security researchers. Only the prefixes of the litellm-database and litellm-non_root digests have been published.

# Defanged. Re-fang only inside your security tooling.
# Network
hxxp://www[.]litellm[.]dev/healthcheck            (exfiltration, HTTP POST)
litellm[.]dev, www[.]litellm[.]dev                 (lookalike domain, registered 13 Oct 2026)
hxxps://raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt   (hourly dead drop)
hxxp://<domain from dead drop>/codepy               (second stage; any request means remote code ran)
HTTP header  X-Token: XWiA8gZNa7NcX2XRoAEb
User-Agent   Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0)
Historic dead drop values: localhost:18909, test.test.com:18909

# Package
litellm==1.107.0 (PyPI, all wheels). Wheel SHA-256 (litellm-1.107.0-cp310-abi3-...):
macosx_10_12_x86_64.whl     7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d
macosx_11_0_arm64.whl       0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a
manylinux_2_28_aarch64.whl  668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6
manylinux_2_28_x86_64.whl   462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7
musllinux_1_2_aarch64.whl   c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054
musllinux_1_2_x86_64.whl    1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00
win_amd64.whl               12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484
litellm-1.107.0.tar.gz      2befe2a79fb4fbbd9a543b5b40b530c8cffa8771bab22b8fb22b2e4ae3b1f819   (sdist, tampered but no payload)

# Docker (tags v1.107.0, latest, main-latest, main-stable while they pointed here)
ghcr[.]io/berriai/litellm:v1.107.0, litellm-database:v1.107.0, litellm-non_root:v1.107.0, docker[.]io/litellm/litellm:v1.107.0
image index    sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e   (litellm, ghcr and Docker Hub)
amd64 manifest sha256:bd1aeee419ea36da9aa2b657288da4101887be468f020ac63d22ba6ed84a3ea5
arm64 manifest sha256:56b74573eed6e4aafe4b50603dbe7853e0345f188c8e44a09f1098caf1f4bcdf
litellm-database index  sha256:c00f9d92c427...   (prefix only published)
litellm-non_root index  sha256:7b00e91cd2fe...   (prefix only published)

# Source
github[.]com/Berri-AI/litellm (lookalike repo), commit 20535d8fa11f786a6c24df7488a0e449ed5f09ad

# Host
# Host files in site-packages (SHA-256, Linux/macOS then Windows CRLF copy)
cook.pth          7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb
                  84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d
cook.py           9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25
                  03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea
sitecustomize.py  34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa
                  b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465
/tmp/.pc_once_72129118c59f5636c0bb   (written only after successful exfiltration)
/tmp/remote_code_loader.lock         (held by the background loader)
/tmp/.pc_sq_*  /tmp/.pc_e_*          (temporary directories)
PRIVCOLLECT_ACTIVE=1                 (environment variable)
Detached python process, parent PID 1, working directory /

LiteLLM 1.107.0 FAQ

Short answers based on BerriAI's incident updates and researcher analysis as of 21 October 2026.

What happened to LiteLLM?

On 21 October 2026, LiteLLM version 1.107.0 was published to PyPI and as Docker images with malware added. LiteLLM is a widely used Python SDK and proxy for calling many AI model providers. The malicious release was built from a lookalike GitHub repository, not from the real LiteLLM code.

What does the malware do?

A file called cook.pth runs at every Python start and launches a stealer that names itself privcollect. It takes cloud credentials, SSH and GPG keys, browser data, AI coding tool credentials, environment variables and LiteLLM proxy database keys, then sends them encrypted to a lookalike domain. A second file starts a background process that checks an attacker-controlled GitHub file every hour and can download and run more code.

Which versions are affected?

Only 1.107.0: all of its PyPI wheels and the v1.107.0 Docker images, plus the latest, main-latest and main-stable tags while they pointed to it on 21 October. Earlier releases, including 1.106.2, are clean.

When was the exposure window?

On 21 October 2026 the malicious PyPI wheels were live from 12:39 to 14:23 BST (11:39 to 13:23 UTC). The Docker tags v1.107.0, latest, main-latest and main-stable pointed to the infected image from 12:46 BST until about 15:20 BST on Docker Hub, and until 14:51 BST on GHCR. Check CI logs, lockfile history and image pulls in those windows.

How did the attacker publish it?

BerriAI says the release was published through three engineers' GitHub accounts using stolen GitHub CLI OAuth tokens, which have been revoked. Its investigation is ongoing.

Is uninstalling enough?

No. Treat any host that installed 1.107.0 as compromised. Rebuild it from a clean image, then rotate every credential it could reach from a separate clean machine. Do not run pip or Python on a suspect host before removing the payload, because that runs the malware again.

Is there a CVE?

No. This is a malicious release, not a software flaw, so there is no CVE. It is tracked in BerriAI's public incident report and in malicious package databases.

What should MSPs do first?

Search every client environment for 1.107.0 in lockfiles, images and CI caches, block the lookalike domain at egress, and prioritise developer laptops, CI runners and LiteLLM proxy hosts, which hold the most valuable credentials.

Detect and Remediate the LiteLLM Attack Across Your Estate

CybaOps finds compromised packages and exposed credentials across every system you look after, whether that's your own business or your clients'. It runs threat hunts through our SOC and drives remediation through to a verified fix, so proactive remediation and reactive hunting happen in one place.