Version 1.107.0 of LiteLLM, software that unifies and manages access to AI models, was found to contain credential-stealing malware and a mechanism for executing remote code. The malicious packages were distributed through PyPI and Docker registries on October 21, 2026. The maintainers say they have removed the affected artifacts and contained the incident. LiteLLM was also compromised in March of the same year, but this time the official GitHub tag contained no malicious files. Instead, a malicious artifact built from a different repository passed through the formal approval process. Moreover, once installed, the stealer code can run during normal Python startup, even in programs that do not use LiteLLM. Reviewing the legitimate source code alone is not enough to judge safety; this is an incident that requires investigating the files actually distributed and the environments where they run.

AD

A malicious artifact that passed the official approval process

According to the maintainers' official report, the attack abused the GitHub credentials of three engineers. A GitHub CLI OAuth token appears to have been stolen, but how the attacker obtained it has not been determined so far. According to the official timeline, the attacker's unauthorized changes to the release process were initially rejected by branch protection. However, the protection settings were overridden using privileged account credentials, and a production release was approved by a different account. Workflow records needed for the investigation were also deleted using yet another set of credentials. The sequence shows that even with a mechanism separating the person who makes a change from the person who approves it, the protection can be defeated if the credentials of both are stolen.

The repository from which the malicious artifact was built also differed from the legitimate one. LiteLLM's official repository is BerriAI/litellm, but the artifact in question was built from Berri-AI/litellm, a name with a hyphen. The official v1.107.0 source tag did not contain the malicious files, so examining the source code alone could not reveal a problem with the files actually delivered to users.

Security firm Socket confirmed this discrepancy in its own investigation by analyzing container build provenance information. The Linux amd64 image it examined recorded Berri-AI as the source owner. The malicious files in that repository matched, byte for byte, the PyPI wheel files Socket inspected. By contrast, in the previous version, 1.106.2, the build provenance pointed to the legitimate BerriAI. Such provenance information is an important clue for tracing which source an artifact was built from, but it does not guarantee the safety of the build origin itself.

According to the maintainers' detailed report, the periods during which the malicious artifacts were available are as follows. All times are in Coordinated Universal Time (UTC) on October 21, 2026.

Distribution channel Affected versions/tags Period malicious artifacts were available
PyPI All 7 wheels of litellm==1.107.0 11:39:51–13:23
Docker Hub v1.107.0, latest, main-latest, main-stable 11:46:56–14:20
GHCR LiteLLM-related images with the same tags Available from 11:46:56; confirmed stopped by 13:51

Environments that used tags whose targets get updated, such as latest, may have pulled the malicious image even without explicitly specifying 1.107.0. Even after distribution was stopped, malicious files may remain in local caches and existing container images, so continued investigation is necessary. The maintainers say customers who obtain LiteLLM from a private enterprise registry were not affected. Users of the open-source version are asked to pin to a previous version confirmed to be safe, such as 1.106.2.

Credential-stealing code that runs without loading LiteLLM

GMO Flatt Security, through an investigation using its Takumi Guard analysis platform, reported that three files, cook.pth, cook.py, and sitecustomize.py, had been added to the malicious wheel. On installation, these files are placed directly under the Python environment's site-packages directory rather than in the LiteLLM library itself. Importantly, this placement means programs that do not use LiteLLM directly may also be affected.

cook.pth contains the statement import cook, which causes the credential-collecting code to be loaded when Python starts. The other entry point, sitecustomize.py, is also a file that Python tries to load automatically at startup. The official Python documentation describes how executable lines in .pth files and sitecustomize are loaded. Because the attacker abuses these standard startup mechanisms, an application does not need to explicitly import LiteLLM. In a Python environment where the malicious files remain, simply launching an ordinary program may execute the stealer code.

According to analyses by Socket and GMO Flatt Security, the credential-collection code uses the name privcollect and has 16 collection modules. Its targets go beyond cloud service credentials to include SSH private keys and data stored in browsers. It also searches for authentication and configuration files used by AI development tools such as Codex, Claude, and Gemini, and on Linux it tries to obtain information from the environment variables of other processes that it has permission to read. In other words, even with the same malware infection, the information at risk of leaking differs depending on where it runs, such as a developer's machine, a CI environment, or an AI gateway.

Credentials managed by LiteLLM itself are also targeted. If the environment variable DATABASE_URL is set, the malware attempts to query LiteLLM_CredentialsTable, which stores credentials, and LiteLLM_ProxyModelTable, which holds model settings. Because LiteLLM can centrally manage API keys for multiple AI services, a compromised environment could put the credentials of many services at risk. For this reason, rotating only the API keys stored in files is not a sufficient response. That said, the existence of code that attempts database access should be distinguished from having actually obtained and decrypted all information in each individual environment.

The destination for the collected information was set to www[.]litellm[.]dev/healthcheck, which appears designed to look like a legitimate diagnostic process. According to Socket, the malware encrypts the collected data with AES-256-CBC and protects the encryption key with an RSA-4096 public key before sending it. Although the URL uses a name suggestive of a health check, it is in fact a destination for exfiltrating credentials and other data.

Separately from credential theft, a mechanism for executing externally obtained Python code was also built in. A resident process launched from sitecustomize.py references domain.txt placed in letters9813/pythonclient-test on GitHub. If a valid destination is specified in this file, it retrieves Python code from there and executes it without verifying the content via signature or hash. After checking the destination, it waits one hour, but this does not mean credential theft succeeded every hour.

The malware's behavior does have constraints depending on the OS and runtime environment. According to JFrog's static analysis, on Windows the startup routine for the resident process, which depends on os.fork(), cannot complete, but the credential theft path via cook.pth remains. In the macOS distribution Socket examined, restrictions were confirmed in some database processing and in the retrieval of browser passwords in plaintext. When Socket checked at 13:01:44 UTC on October 21, domain.txt, which specifies the remote code source, was also empty. However, even if the remote code execution path did not work, the independently operating credential-collection code is not thereby disabled. The failure of a particular function cannot be taken as evidence that the whole environment is safe.

AD

Recovery requires separately verifying artifacts, runtime environments, and credentials

The maintainers urge that, in potentially affected environments, remediation not begin with pip install. Because pip itself runs on Python, checking state or reinstalling packages could cause the malicious files to execute again. Socket likewise recommends preserving evidence with trusted tools, isolating affected hosts and containers, and then rebuilding the environment. Simply uninstalling LiteLLM may leave behind the malicious files embedded in Python's startup process and any resident processes.

In this incident, the legitimate source tag, the actual distributed artifacts, and the running environments each need to be verified as separate targets. Even if the official tag is clean and the malicious version has been removed from the distribution source, the safety of environments where it was already installed cannot be proven. Based on the maintainers' official report and Socket's analysis of the startup process, the targets to check and the extent of what each piece of evidence can establish are summarized below.

What to check Evidence in this incident What it cannot tell you alone
Source tag The official tag contains no malicious files Whether the actually distributed wheels or container images are safe
Artifacts and build provenance Actual files, build source owner and revision, digest of the running image What was executed after installation
Runtime environment Startup-related files, resident processes, network logs, installation history Whether a leak can be ruled out when there is no evidence
Credentials Keys readable from the process, databases, cloud permissions Whether removing the malware alone prevents misuse of leaked keys

What stopping distribution prevents is new retrieval of the malicious package. In environments that already installed the malicious version, deleting LiteLLM itself may leave the malicious files directly under site-packages and any resident processes. The maintainers therefore recommend rebuilding using a clean container image or Python virtual environment. If credentials may have been sent externally, the relevant credentials must be revoked and reissued from a secure environment separate from the infected one. Removing the malware and revoking credentials need to proceed as independent responses.

The credentials the maintainers ask users to check include not only the API keys for each AI provider stored in LiteLLM's proxy database but also the master key and virtual keys. Database connection passwords and cloud IAM roles available to the runtime environment are also subject to investigation. Considering the AI development tool credentials revealed by GMO Flatt Security's analysis, it is not appropriate to limit the scope to LiteLLM-specific API keys. It is necessary to determine which files, services, and permissions the compromised process could actually access and to identify the credentials that may have leaked.

On the other hand, the absence of marker files or lock files that would indicate infection does not guarantee safety, since replacing containers or deleting temporary files can erase traces. Nor can the mere presence of sitecustomize.py be taken as proof of infection, because the file is also used by legitimate Python mechanisms. Rather than relying on file names, it is important to examine contents and cross-check execution history and network logs.

In response to the incident, the maintainers revoked related tokens, temporarily restricted new joins to the GitHub organization, and removed trust relationships with registries. However, the investigation into how the attacker first obtained credentials continues, and no evidence has been presented that the same attacker or intrusion route was behind the March compromise. What this incident has revealed is that keeping a record of release approvals alone cannot sufficiently guarantee the safety of distributed artifacts. A mechanism that permits publication only of artifacts generated from pre-approved repositories and revisions will be important for supply chain protection. On the user side as well, in addition to checking the legitimate source, it is necessary to cross-check the packages actually obtained and the running container images, verifying safety from distribution through execution.