~/f4n6 $ grep -r "LiteLLM supply chain attack steals cloud and AI credentials via malicious package" ./investigations/ --include="*.md"

LiteLLM supply chain attack steals cloud and AI credentials via malicious package

Jeff Davies 21 Oct 2026 8 min read

1. Executive summary

A malicious release of the LiteLLM Python package, version 1.107.0, was published to PyPI at 11:39 UTC on 21 October 2026 and pulled within hours. Every compiled wheel for macOS, Linux (glibc and musl) and Windows carries a credential stealer and an hourly remote-code loader, and the matching Docker image litellm/litellm:1.107.0 was distributed through Docker Hub and GHCR before removal. The package is an AI gateway that sits next to provider API keys, cloud identities and database connection strings, so any environment that installed 1.107.0 or pulled the affected image tags should assume those secrets are compromised. No CVE has been assigned and no exploitation status is recorded against this item. The exposure for EMEA financial services is concentrated in developer laptops, CI runners and production AI proxy containers that hold cloud and LLM provider credentials.

2. Regulatory framing

Article Trigger (the fact in this item) Practical impact
DORA Art. 28 A third-party Python package and container image used inside the firm's AI gateway was compromised at the upstream maintainer and distributed through PyPI, Docker Hub and GHCR Firms must treat the LiteLLM dependency as an ICT third-party arrangement, identify which internal services depend on it, and record the compromise against their third-party risk register
DORA Art. 30 The compromised artefact was pulled from public registries under the maintainer's own release process, with no provenance attestation tying the build to a CI run Contractual provisions with the maintainer or with any reseller of the gateway should be checked for notification duties and for the right to audit build integrity
NIS2 Art. 21(2)(d) The compromise entered through the software supply chain of a package the firm did not build, and the malicious change was a one-line edit to the build configuration Supply chain security measures must cover integrity verification of third-party packages and container images before they reach production

3. Technical analysis & attack chain

The compromise was carried out by injecting three files into the LiteLLM build so that they land in the root of site-packages and execute on every Python interpreter start in that environment. No import of litellm is required. The source distribution carries no payload but does carry the build-config change that pulled the payload into the wheels.

Confirmed steps:

  1. A lookalike GitHub repository, github.com/Berri-AI/litellm (hyphenated, against the legitimate BerriAI organisation), was used to inject the malicious files into the release pipeline. This attribution of the injection point is reported by Wiz and should be treated as single-sourced until corroborated.
  2. The attacker added one line under [tool.maturin] in pyproject.toml: data = "cook". That line is not present at the v1.107.0 git tag (commit 66c8f5b1a9). Maturin's data option copies a local directory into the wheel's .data/ tree, so the cook/ directory, present in the build environment but absent from the sdist, was bundled into the wheels.
  3. All seven 1.107.0 wheels (macOS, Linux glibc, Linux musl, Windows) carry cook.pth, cook.py and sitecustomize.py. The first three entries in the manylinux x86_64 wheel's RECORD are litellm-1.107.0.data/purelib/cook.pth, cook.py and sitecustomize.py. No earlier release and no 1.107.0 release candidate contains them. Every Python source file under litellm/ in the wheel is byte-identical to the sdist; the tampering is limited to the build config and the three injected files.
  4. cook.pth causes cook.py to run automatically every time Python is invoked in the environment. cook.py is the infostealer, which calls itself privcollect. sitecustomize.py is the remote access trojan, executed by Python at interpreter startup.
  5. The stealer harvests data across 16 modules: browser credentials and cookies from Chrome, Firefox, Edge and Safari; AWS credentials from ~/.aws/; environment variables; EC2/ECS instance metadata (IMDS); Google Cloud Platform service account keys and application default credentials; Microsoft Azure tokens from the CLI cache; API keys for OpenAI, Anthropic, Cohere and other LLM providers; SSH private keys; GPG keys; shell history; and the provider API keys stored in the LiteLLM proxy database. Socket reports coverage of the configs of more than 20 AI coding tools.
  6. The bundle is encrypted with AES-256-CBC, the encryption key is wrapped with an RSA-4096 public key, and the result is sent by HTTP POST to http://www[.]litellm[.]dev/healthcheck. The domain litellm.dev was registered on 13 October 2026 at 00:45 UTC, a week before the upload.
  7. The RAT spawns a background daemon that polls attacker infrastructure every hour for new commands and executes whatever Python is served. StepSecurity reports the dead drop is hosted on a GitHub account, letters9813, created six hours after the domain registration on 13 October 2026. The Register describes the polling target as attacker-controlled infrastructure without naming it; the GitHub dead-drop detail is single-sourced to StepSecurity.

Persistence and execution: the .pth and sitecustomize.py mechanism means the payloads run in any Python process started in the affected environment, including proxy containers and CI runners, without user action. There is no evidence in the sources of privilege escalation, lateral movement or a CVE. The impact is credential theft and remote code execution under the identity running Python.

Distribution and reach: LiteLLM has shipped as maturin-built platform wheels since the 1.10x line, so almost every install pulls a wheel rather than the sdist, and a wheel-only payload reached essentially every 1.107.0 user. The project released 12 times across four minor lines between 17 and 21 October, and many projects depend on it with an open-ended litellm>= constraint, so a fresh install or lockfile refresh would have picked up 1.107.0 as soon as it was published. The most recent safe version is v1.106.2. PyPI quarantined the release within hours and the Docker image was removed from Docker Hub and GHCR soon after. LiteLLM wheels carry no PyPI provenance attestations, so PyPI cannot show which workflow built and uploaded 1.107.0.

Prior incident: this is the second LiteLLM compromise this year. Malicious releases 1.82.7 and 1.82.8 sat on PyPI for about 40 minutes in March 2026. CloudSEK, in a dataset built from roughly 434,000 files the attackers captured, maps potential exposure to more than 2,500 organisations and 434,000 CI/CD pipelines. SecurityWeek attributes the March incident to the Trivy hack. That figure is a CloudSEK estimate and is not a measurement of the October incident; the scale of the current compromise is not yet known.

Attribution: no actor is named in any source and no MITRE ATT&CK profile is associated with this item. The Register describes the operators as unknown criminals. Attribution is unconfirmed.

4. Mitigation & containment

P1 within 24 hours:

  • Search every environment for /tmp/.pc_once_* and /tmp/remote_code_loader.lock. If /tmp/.pc_once_* exists, the exfiltration has already fired. If /tmp/remote_code_loader.lock exists, the C2 daemon ran or is still running. Treat either as a confirmed compromise of every secret reachable from that environment.
  • Stop deploying 1.107.0. Pin to v1.106.2 or earlier and rebuild. Check lockfiles and any litellm>= constraint that could resolve to 1.107.0.
  • Identify every host, CI runner and container that ran Python after installing 1.107.0, including proxy containers and CI runners, and investigate them.
  • Rotate every credential reachable from an affected environment: AWS keys and IMDS-derived credentials, GCP service account keys and application default credentials, Azure CLI tokens, OpenAI, Anthropic, Cohere and other provider API keys, the LiteLLM proxy database credentials, SSH private keys, GPG keys, and browser-stored passwords and cookies. Rotate the proxy database's stored provider keys as well.
  • Block egress to litellm.dev and to the GitHub dead drop if the account is confirmed, and hunt for HTTP POSTs to /healthcheck on that domain.

P2 within 72 hours:

  • Remove the Docker image litellm/litellm:1.107.0 from any registry mirror and from hosts. Audit pulls of the latest, main-latest and main-stable tags, which resolved to the compromised image during the window.
  • Review CI/CD pipeline logs for installs of 1.107.0 and for outbound connections to the lookalike domain from build agents.
  • Check for the lookalike repository github.com/Berri-AI/litellm in any dependency, mirror or vendoring configuration.

P3 within 7 days:

  • Require hash-pinned or lockfile-pinned dependencies with integrity verification for Python packages and container images used in AI infrastructure.
  • Add provenance and signature verification to the build pipeline for any package that runs next to production credentials, and reject releases without attestations where the vendor offers them.
  • Extend secret-scanning and egress monitoring to AI gateway containers and developer laptops, since the payload targets browser stores and CLI caches that endpoint controls often miss.

5. Indicators of compromise

type value confidence source
domain www[.]litellm[.]dev high The Register, StepSecurity
url hxxp://www[.]litellm[.]dev/healthcheck high The Register
file /tmp/.pc_once_* high Aikido Security (via The Register)
file /tmp/remote_code_loader.lock high Aikido Security (via The Register)
file cook.pth high StepSecurity, The Register
file cook.py high StepSecurity, The Register
file sitecustomize.py high StepSecurity, The Register
package litellm 1.107.0 high StepSecurity, The Register
package litellm 1.82.7 high StepSecurity (March incident)
package litellm 1.82.8 high StepSecurity (March incident)
container litellm/litellm:1.107.0 high The Register
github github.com/Berri-AI/litellm medium Wiz (via The Register), single-sourced
github letters9813 medium StepSecurity, single-sourced
domain  www[.]litellm[.]dev
url  hxxp://www[.]litellm[.]dev/healthcheck
file  /tmp/.pc_once_*
file  /tmp/remote_code_loader.lock
file  cook.pth
file  cook.py
file  sitecustomize.py
package  litellm 1.107.0
package  litellm 1.82.7
package  litellm 1.82.8
container  litellm/litellm:1.107.0
github  github.com/Berri-AI/litellm
github  letters9813

No file hashes are published in the sources. The GitHub dead-drop account and the lookalike repository are single-sourced; verify before enforcement.

6. Detection

The .pth and sitecustomize.py mechanism gives a reliable file-based detection: any cook.pth, cook.py or sitecustomize.py in the root of a LiteLLM site-packages is not part of a legitimate release.

rule LiteLLM_1_107_0_SupplyChain_Payload
{
    meta:
        author = "Adverse Trace"
        date = "2026-10-21"
        reference = "https://www.stepsecurity.io/blog/litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealer"
        description = "Detects the cook.pth, cook.py and sitecustomize.py files injected into LiteLLM 1.107.0 wheels"
    strings:
        $pth = "cook.py" ascii
        $stealer = "privcollect" ascii
        $exfil = "/healthcheck" ascii
        $domain = "litellm.dev" ascii
        $lock = "remote_code_loader.lock" ascii
        $once = ".pc_once_" ascii
    condition:
        uint32(0) == 0x04034b50 or
        (2 of ($stealer, $exfil, $domain, $lock, $once)) or
        ($pth and 1 of ($stealer, $exfil, $domain, $lock, $once))
}
title: LiteLLM 1.107.0 payload execution and exfiltration
id: 8f3c2a71-5d4e-4b9a-9c1e-7a2b6d0f4e13
status: experimental
description: Detects Python processes writing the LiteLLM 1.107.0 payload markers or posting to the lookalike exfiltration endpoint
author: Adverse Trace
date: 2026/10/21
references:

  - https://www.theregister.com/security/2026/10/21/litellm-supply-chain-attack-hoovers-up-passwords-and-secrets/5304548
logsource:
  category: process_creation
  product: linux
detection:
  selection_python:
    Image|endswith:

      - '/python'
      - '/python3'
  selection_marker:
    CommandLine|contains:

      - 'cook.py'
      - 'sitecustomize.py'
      - 'privcollect'
  condition: selection_python and selection_marker
falsepositives:

  - Legitimate sitecustomize.py shipped by other packages; correlate with the LiteLLM site-packages path
level: high

For network detection, alert on any HTTP POST to www.litellm.dev with path /healthcheck, and on DNS resolution of litellm.dev from build agents, developer laptops or AI gateway containers. For host detection, alert on creation of /tmp/.pc_once_* or /tmp/remote_code_loader.lock.

7. Sources

  • The Register, "LiteLLM supply chain attack hoovers up passwords and secrets", https://www.theregister.com/security/2026/10/21/litellm-supply-chain-attack-hoovers-up-passwords-and-secrets/5304548, 2026-10-21
  • StepSecurity, "litellm 1.107.0 Compromised on PyPI: Backdoored Wheels Drop a Credential Stealer and an Hourly Remote Code Loader", https://www.stepsecurity.io/blog/litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealer, 2026-10-21
  • The Hacker News, "LiteLLM Compromised in Supply Chain Attack Delivering Credential Stealer and Backdoor", https://thehackernews.com/2026/10/litellm-compromised-in-supply-chain.html, 2026-10
  • The Hacker News, "Malicious LiteLLM Releases Tied to Trivy Hack May Have Exposed 2,100+ Organizations", https://thehackernews.com/2026/08/malicious-litellm-releases-tied-to.html, 2026-08
  • SecurityWeek, "Over 2,500 Organizations Impacted by LiteLLM Supply Chain Attack", https://www.securityweek.com/over-2500-organizations-impacted-by-litellm-supply-chain-attack/, 2026

8. Adverse Trace position

No CVE has been assigned and no exploitation status is recorded, so severity here rests on exposure rather than a CVSS score. The exposure is high for any firm that ran LiteLLM 1.107.0 or the affected Docker tags, because the payload executes on every Python start and targets exactly the credentials an AI gateway holds. Attribution is unconfirmed and the scale of the October incident is not yet known; the 2,500-organisation figure belongs to the March incident and should not be applied here. We assess that the March and October compromises of the same package indicate a repeatable attack on the LiteLLM release process rather than a one-off, and we will track the vendor's remediation and any provenance controls it adds. Clients should treat any environment that installed 1.107.0 as compromised and rotate credentials before restoring service.


Read the original source →

Published via PulseTrace — Adverse Trace threat intelligence.

Post this to LinkedIn
Formatting is converted automatically — headings, bullets, a link back & hashtags. Paste straight in.
J
Jeff Davies