~/f4n6 $ grep -r "LiteLLM supply chain attack steals cloud creds, triggers Bedrock access" ./investigations/ --include="*.md"

LiteLLM supply chain attack steals cloud creds, triggers Bedrock access

Jeff Davies 22 Oct 2026 9 min read

1. Executive summary

On 21 October 2026 LiteLLM's release pipeline was compromised and version 1.107.0 was published to PyPI and Docker Hub carrying a credential stealer and a remote code loader. The malicious package was live on PyPI from 11:39 to 13:23 UTC and the Docker images tagged 1.107.0, latest, main-latest and main-stable served the bad build from 11:46 to 14:20 UTC. Any EMEA financial services firm that installed or pulled 1.107.0 during those windows, including through an open-ended litellm>= constraint or a lockfile refresh, should treat every credential reachable from that environment as compromised. Wiz observed stolen AWS credentials being validated about four and a half hours after exfiltration and checked for access to Amazon Bedrock models, activity linked to LLMjacking. No CVE has been assigned and no CISA KEV entry exists for this item.

2. Regulatory framing

Article Trigger (the fact in this item) Practical impact
DORA Art. 28 The compromise entered client environments through a third-party software dependency (LiteLLM 1.107.0 on PyPI and Docker Hub), not through the client's own code. ICT third-party risk controls must cover the integrity of the software supply chain for AI gateway components, including how releases are verified before deployment.
DORA Art. 30 Clients consuming LiteLLM as a hosted or managed AI gateway depend on the provider's release pipeline, which was itself the intrusion path. Contractual provisions with the ICT third-party provider should address notification of supply chain compromise and the provider's release integrity controls.
NIS2 Art. 21(2)(d) The malicious build reached downstream users via a compromised upstream release process, a supply chain security failure. Entities in scope must be able to evidence supply chain security measures covering software dependencies of this kind.

3. Technical analysis & attack chain

The attacker did not exploit a vulnerability in LiteLLM's code. They compromised the release process and shipped a malicious build through the normal distribution channels.

  1. LiteLLM found an unexpected, innocuously named user account in its internal LiteLLM deployment, which was exposed to the public internet. The company believes the attacker gained access to this deployment.
  2. GitHub CLI OAuth tokens were lifted from that deployment's logs. LiteLLM has observed situations where Claude Code embeds a user's GitHub CLI OAuth token into a response body, so where response bodies are logged those tokens can appear in LiteLLM logs.
  3. The attacker used the GitHub accounts of three LiteLLM engineers, apparently via the stolen GitHub CLI OAuth tokens. One account changed the release pipeline and triggered the release, a second approved it, and a third deleted the workflow records, limiting the logs available to investigators.
  4. Version 1.107.0 was published to PyPI at 11:39 UTC and to Docker Hub and GHCR at 11:46 UTC. The Docker tags v1.107.0, latest, main-latest and main-stable all served the bad build until 14:20 UTC. PyPI quarantined the package at 13:23 UTC.
  5. On install, pip copied three files into the root of site-packages: cook.pth, cook.py and sitecustomize.py. Python executes both payloads on every interpreter start in that environment, whether or not litellm is imported.
  6. cook.py is the credential stealer, which calls itself privcollect. sitecustomize.py is the remote code loader, which forks a background daemon that polls a GitHub dead drop every hour and runs whatever Python the attacker serves.
  7. The stealer encrypts the collected data with AES-256-CBC, wraps the encryption key with an RSA-4096 public key, and sends it by HTTP POST to http://www[.]litellm[.]dev/healthcheck.
  8. Wiz observed the stolen credentials in use about four and a half hours after exfiltration. The attacker validated AWS credentials taken from compromised CI runners and Kubernetes nodes and checked whether they could reach AI models on Amazon Bedrock. In a small number of environments the attacker listed IAM roles, users and access keys and looked up account and logging details.

The build tampering is narrow. StepSecurity found the sdist's pyproject.toml carries a data = "cook" line under [tool.maturin] that is not present at the v1.107.0 git tag (commit 66c8f5b1a9). 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. The cook/ directory existed in the build environment but was left out of the sdist, so the GitHub source tree looks clean and the sdist looks almost clean while all seven wheels carry the payload. The wheels carry no PyPI provenance attestations, so PyPI cannot show which workflow built and uploaded 1.107.0. Build records for the container image show the release workflow recorded a repository called Berri-AI/litellm as its source, one hyphen away from the legitimate BerriAI/litellm project.

The stealer targets 16 modules. It takes browser credentials and cookies from Chrome, Firefox, Edge and Safari; AWS credentials from ~/.aws/, environment variables and 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 and shell history; Git credentials, Kubernetes and Docker credentials, saved browser logins, browsing history; authentication files for Codex, Claude, Gemini and Cursor; and the environment of every running process. It also tries to pull stored credentials and model settings from the database of LiteLLM proxy deployments, which shows intent but does not prove the attacker succeeded against any particular deployment.

The most recent safe version is v1.106.2. LiteLLM states all previous versions are safe and the impacted releases have been pulled. Enterprise customers using LiteLLM's private registry were not affected.

Confidence caveats. LiteLLM has not confirmed how the attacker gained access to its internal deployment and suspects a recently patched vulnerability; that is unconfirmed. The attribution of the March 2026 LiteLLM compromise to the Trivy hack rests on SecurityWeek and The Hacker News reporting and is separate from this October event. No threat actor has been named in any source and no MITRE ATT&CK profile applies, so attribution is unconfirmed. The March exposure figures (2,488 corporate domains per Hudson Rock, close to 2,500 organisations per CloudSEK, 434,000 CI/CD pipelines per CloudSEK) describe the earlier incident, not this one.

4. Mitigation & containment

P1 within 24 hours.

  • Search every Python environment, container image and CI runner for the three injected files: cook.pth, cook.py and sitecustomize.py in the root of site-packages. Their presence means the environment ran the payload.
  • Check for /tmp/.pc_once_* (the exfiltration has already fired if this file exists) and /tmp/remote_code_loader.lock (the C2 daemon ran or is still running if this file exists), per Aikido's guidance.
  • Treat every credential reachable from an affected environment as compromised and rotate it: AWS access keys and IAM users, Azure tokens, GCP service account keys, Kubernetes and Docker credentials, Git credentials, SSH and GPG keys, and provider API keys for OpenAI, Anthropic, Cohere and any other LLM provider configured in the environment.
  • Review AWS CloudTrail for credential validation and Bedrock model access from CI runner and Kubernetes node identities in the hours after any suspected install, and for IAM role, user and access key enumeration.
  • Block outbound traffic to litellm[.]dev at the proxy and DNS layer. The legitimate project domain is not litellm.dev; the lookalike was registered on 13 October 2026 at 00:45 UTC.
  • Pin LiteLLM to v1.106.2 or earlier and remove any litellm>= open-ended constraint from requirements files and lockfiles.

P2 within 72 hours.

  • Audit GitHub organisation membership and OAuth grants for GitHub CLI tokens, revoke tokens issued to engineering staff that are not needed, and review release workflow approval records for gaps where workflow logs were deleted.
  • Enable and require PyPI provenance attestations for internal packages, and verify attestations on third-party packages before deployment where the publisher provides them.
  • Stop logging full LLM response bodies in any LiteLLM proxy deployment, or redact GitHub CLI OAuth tokens from them, since that logging path is how the tokens reached the attacker.

P3 within 7 days.

  • Add a CI gate that fails a build when a wheel's RECORD contains files not present in the source tree, and diff installed site-packages against the sdist manifest.
  • Review DORA Art. 28 and Art. 30 arrangements with AI gateway and LLM provider suppliers to confirm they commit to notifying supply chain compromise and to release integrity controls.

5. Indicators of compromise

type value confidence source
domain litellm[.]dev high LiteLLM, Socket, StepSecurity
url hxxp://www[.]litellm[.]dev/healthcheck high The Register, StepSecurity
file path cook.pth (site-packages root) high StepSecurity, The Register
file path cook.py (site-packages root) high StepSecurity, The Register
file path sitecustomize.py (site-packages root) high StepSecurity, The Register
file path /tmp/.pc_once_* high Aikido via The Register
file path /tmp/remote_code_loader.lock high Aikido via The Register
package litellm 1.107.0 (PyPI) high LiteLLM, StepSecurity
container image litellm/litellm:1.107.0, latest, main-latest, main-stable high The Register, Help Net Security
repository github.com/Berri-AI/litellm high Wiz via The Register
account GitHub account letters9813 (dead drop host) medium StepSecurity

No file hashes are present in the sources, so none are listed. The GitHub dead drop file was empty when Socket checked it on 21 October; its path is not given in the sources.

domain  litellm[.]dev
url  hxxp://www[.]litellm[.]dev/healthcheck
file  cook.pth
file  cook.py
file  sitecustomize.py
file  /tmp/.pc_once_*
file  /tmp/remote_code_loader.lock
package  litellm 1.107.0
container  litellm/litellm:1.107.0
container  litellm/litellm:latest
container  litellm/litellm:main-latest
container  litellm/litellm:main-stable
repository  github.com/Berri-AI/litellm
account  letters9813

Behavioural indicators

behaviour where to observe confidence
Python interpreter start spawns a background daemon polling a GitHub file hourly EDR process telemetry, outbound HTTPS to github.com from Python processes high
HTTP POST of AES-256-CBC encrypted bundle to litellm[.]dev/healthcheck proxy and DNS logs high
Reads of ~/.aws/, GCP ADC and service account keys, Azure CLI token cache, SSH and GPG key files by a Python process EDR file access telemetry high
AWS credential validation and Bedrock model listing from CI runner or Kubernetes node identities CloudTrail high
IAM role, user and access key enumeration and account/logging lookups CloudTrail medium (small number of environments per Wiz)

6. Detection

rule PY_LiteLLM_SupplyChain_Stealer_Oct2026
{
    meta:
        author = "Adverse Trace"
        date = "2026-10-22"
        reference = "https://www.stepsecurity.io/blog/litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealer"
        description = "Detects the cook.py stealer and sitecustomize.py loader injected into litellm 1.107.0 wheels"
    strings:
        $a = "privcollect" ascii
        $b = "litellm.dev/healthcheck" ascii
        $c = "www.litellm.dev" ascii
        $d = "remote_code_loader.lock" ascii
        $e = ".pc_once_" ascii
        $f = "cook.pth" ascii
    condition:
        uint32(0) != 0xfeedface and 2 of them
}
title: LiteLLM 1.107.0 Stealer Exfiltration and Loader Daemon
id: 8f3c2a71-4b6e-4d2a-9c1f-7e5a0b3d9c42
status: experimental
description: Detects Python processes writing the LiteLLM 1.107.0 stealer marker files or posting to the litellm.dev exfiltration endpoint
author: Adverse Trace
date: 2026-10-22
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_paths:
        CommandLine|contains:

            - '.pc_once_'
            - 'remote_code_loader.lock'
    condition: selection_python and selection_paths
falsepositives:

    - None expected; these filenames are specific to the malicious build
level: critical
title: Outbound Connection to litellm.dev Lookalike Domain
id: 1d6b9e04-2c8a-4f57-b3e1-9a0c5d7f2b18
status: experimental
description: Detects DNS or proxy traffic to the litellm.dev domain used for credential exfiltration
author: Adverse Trace
date: 2026-10-22
references:

    - https://www.stepsecurity.io/blog/litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealer
logsource:
    category: dns
detection:
    selection:
        QueryName|endswith: 'litellm.dev'
    condition: selection
falsepositives:

    - None expected; the legitimate project does not use this domain
level: critical

7. Sources

  • Help Net Security, "LiteLLM hit by second supply chain attack this year, users urged to rotate credentials", https://www.helpnetsecurity.com/2026/10/22/litellm-compromised-supply-chain-attack-pypi-docker/, 2026-10-22.
  • 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 Suspects GitHub Token Leak in AI Gateway Logs Behind Malicious Package Release", https://thehackernews.com/2026/10/litellm-suspects-github-token-leak-in.html, 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-21.
  • 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-08.

8. Adverse Trace position

No CVE has been assigned and there is no CISA KEV entry, so this advisory carries no CVSS score; the risk is the credential exposure, not a patchable flaw. Any client that ran LiteLLM 1.107.0, or pulled the latest, main-latest or main-stable Docker tags between 11:46 and 14:20 UTC on 21 October, should assume full compromise of every secret in that environment and act on the P1 steps today. The Bedrock access check and IAM enumeration Wiz observed are the leading indicator of LLMjacking, and clients with Bedrock or other LLM provider spend should review billing and model access logs for the same window. The technical detail on the injected files and the exfiltration endpoint is corroborated across LiteLLM, Socket, StepSecurity, Wiz and Aikido; the initial access vector into LiteLLM's own deployment is single-sourced to LiteLLM and unconfirmed, and no actor is attributed. We will monitor for a published dead-drop path and for any confirmed exploitation against downstream organisations, and will issue an update if either appears.


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