Key facts
- Microsoft Threat Intelligence published an analysis of the LiteLLM 1.107.0 supply chain compromise on October 23, 2026.
- A compromised LiteLLM 1.107.0 release reached the Python Package Index and official container images on October 21, 2026.
- The package included files that Python runs during normal interpreter startup.
- In one Windows case, installing an unrelated dependency with Python activated the collector.
Microsoft Threat Intelligence published an analysis on Oct. 23, 2026, describing how attackers compromised the LiteLLM 1.107.0 release that reached the Python Package Index and official container images on Oct. 21, 2026, and abused Python startup hooks to steal credentials and load remote code.
According to LiteLLM maintainers, stolen developer GitHub credentials changed the release workflow and pointed it at Berri-AI/litellm rather than BerriAI/litellm. A separate developer account credential fulfilled a production approval step. Microsoft has not independently established how the attacker got into the upstream environment or acquired the credentials.
Files cook.pth, cook.py, and sitecustomize.py under litellm-1.107.0.data/purelib/ in the compromised wheel were relocated by installation into the library directory of the environment, outside the application directory. The placement allowed Python’s normal site initialization to process executable import statements in .pth files and then import sitecustomize. Two execution paths were identified by Microsoft: a credential collector started through a path extension and a Unix-oriented loader maintained through site-specific configuration.
In the first path, cook.pth contained import cook, which loaded cook.py to Base64-decode and zlib-decompress an embedded program before executing it. The program called itself PRIVCOLLECT and gathered credentials in a daemon thread. Before launching the thread, the collector checked PRIVCOLLECT_ACTIVE; a nonempty value halted it, otherwise it set the flag to limit duplicate collection in descendant processes. Following an HTTP 200 upload response, the collector tried to write /tmp/.pc_once_72129118c59f5636c0bb.
The duplicate-suppression gates were not containment controls because starting up alone did not prove collection or upload finished. A second startup mechanism used sitecustomize.py as a distinct Unix path with an embedded collector and remote code retrieval and execution functionality not confirmed by Microsoft. The malicious code enabled credential collection and, on Unix systems, retrieval and execution of additional Python code.
When Python starts, the loader locks /tmp/remote_code_loader.lock to allow only one instance per host before it moves into the background. On every cycle, the loader reads a GitHub-hosted domain.txt file that serves as a changeable pointer to an attacker-controlled server. If a valid server address resolves, the loader requests /codepy, compiles the content, and runs it as Python code in the environment. The loader allows the attacker to change the second-stage payload without publishing another compromised package, and it operates separately from the credential collector.
Researchers found domain.txt empty, with no confirmed second-stage retrieval or execution. The file remains changeable.
Authentication material was collected by the tool from developer tools, AI applications, cloud environments, browsers, and infrastructure through multiple sequential modules with independent error handling. The package also included a separate database module that attempted to read credential and model-configuration records from the LiteLLM proxy.
The payload serializes results and metadata as JSON and creates a 32-byte AES key and 16-byte IV per run. AES-256-CBC encrypts the collection document while a 4,096-bit RSA public key wraps the AES key using OAEP. The OpenSSL path attempts SHA-256 then SHA-1 for OAEP and records the selected digest in metadata.
The archive contains data.bin with the IV and encrypted collection, key.bin with the wrapped AES key, and hdr.json with plaintext metadata. The OpenSSL backend builds .pc_e_ temporary directories, stages input and output files, and removes them after use. The collector sends data to hxxp://www[.]litellm[.]dev/healthcheck with application/octet-stream, a browser-like User-Agent, and an X-SHA256 body checksum, repeating the attempt until it receives HTTP 200.
A LiteLLM gateway typically sits between applications and model providers and can reach model-provider API keys, database connection strings, workload identities, routing settings, and tenant policy data. The package also sees use on developer workstations, build agents, test systems, and containers. Startup mechanisms ran malicious code automatically, so exposure extended beyond systems actively using LiteLLM gateway functions. Developer workstations, CI/CD agents, test environments, containers, and other systems that start Python with the package installed could execute the payload.
Endpoint observations on Windows and macOS matched the collector’s discovery, encryption, and outbound-connection behavior. In one Windows case, installing an unrelated dependency using Python activated the collector. Starting Python in an affected environment might activate the malicious code even when LiteLLM was never imported, and removing only application files could leave startup components behind.
Microsoft advises identifying LiteLLM 1.107.0 across installed environments, uv and pip caches, internal mirrors, lock files, build outputs, and container images, then comparing artifacts with customer-ready hashes. Microsoft advises using container digests instead of mutable tags because digests identify immutable image content. Organizations should isolate affected systems, stop Python processes where safe, and prevent automation from restarting them during investigation.
Avoid running python, pip, or interpreter-invoking commands during evidence collection; use trusted tools from a known-clean system for inspection. Uninstalling the package or release tag does not constitute sufficient recovery; organizations must address the affected Python environment, surviving processes, and accessible credentials. Microsoft advises rebuilding from verified artifacts and confirming that cook.pth, cook.py, and sitecustomize.py are gone from the library path.
Microsoft advises rotating reachable credentials from a known-clean machine. That includes model-provider keys, cloud credentials, CI/CD secrets, source-control tokens, SSH and GPG keys, AI tool tokens, and browser sessions. On proxy hosts, stored provider credentials and DATABASE_URL should be included in rotation, and affected identity sessions should be revoked.
Microsoft advises that teams correlate file hashes, process ancestry, .pc_e_ staging, network destination, workload identity, and cloud or identity use before declaring compromise. Teams should also use hash-pinned lock files, verified package and image provenance, container digests over floating tags, and review before adding packages to internal mirrors. Microsoft advises restricting outbound HTTP access through managed egress controls and allowlists on developer workstations, build agents, test systems, containers, and AI gateway hosts.
Microsoft advises onboarding supported systems to Microsoft Defender for Endpoint with real-time and cloud-delivered antivirus protection enabled. As of Oct. 22, 2026, Microsoft Defender Antivirus signatures and Defender for Endpoint alerts were available for activity tied to the compromised release, though names and availability may change. Advanced hunting queries support investigation but serve as leads, not standalone verdicts, and require correlation with environment, process, and identity evidence.
The domain connection query filters out suffix lookalikes such as www[.]litellm[.]dev[.]example and still requires process and workload context. The four startup-file hashes include LF and CRLF variants; a missing SHA-256 field limits the hunt and a generic filename is not equivalent. The cloud process query flags OpenSSL public-key encryption through /tmp/.pc_ staging paths that match key wrapping ahead of possible exfiltration.
Microsoft charted initial access to T1195.001 Compromise Software Dependencies and Development Tools based on malicious files in LiteLLM 1.107.0 wheels and images. Persistence maps to T1546.018 Event Triggered Execution: Python Startup Hooks based on cook.pth and sitecustomize.py. Execution maps to T1059.006 Command and Scripting Interpreter: Python based on the collector running in the interpreter. Defense evasion maps to T1027.013 Obfuscated Files or Information: Encrypted/Encoded File based on Base64-encoded, zlib-compressed collector source, and to T1140 Deobfuscate/Decode Files or Information based on cook.py decoding and decompressing the collector at runtime.

Join the discussion