Back to Intelligence

LiteLLM Supply Chain Compromise: Leaked Master Key Led to Malicious PyPI Package — Detection and Response Guide

SA
Security Arsenal Team
October 24, 2026
12 min read

LiteLLM disclosed on Friday that a threat actor pushed a malicious version of its widely deployed Python package after obtaining an Agent Platform master key that was accidentally committed to the public LiteLLM-Labs/lite-harness GitHub repository on May 27, 2026. The leaked key — embedded in a configuration file — ultimately gave the attacker the access needed to harvest GitHub tokens and hijack the project's release pipeline, turning a routine pip install litellm --upgrade into a supply chain infection vector.

This is the nightmare scenario for any organization running AI/LLM tooling in production. LiteLLM sits at the center of thousands of LLM proxy deployments, brokered API gateways, and agentic AI frameworks. If your developers, CI/CD runners, or production services pulled the malicious package version during the exposure window, you must assume downstream credential theft: LiteLLM deployments routinely hold OpenAI, Anthropic, Azure, and internal API keys in environment variables — exactly what a poisoned package would target first.

This post breaks down the attack chain, gives you concrete detection logic for your SOC, and walks through containment and remediation.

Technical Analysis

What Happened

The root cause was not a code vulnerability — it was a secret management failure. On May 27, 2026, a configuration file containing a live master key for the LiteLLM Agent Platform deployment was committed to the public lite-harness repository. Master keys in LiteLLM's proxy architecture are the crown jewels: they permit administrative operations including virtual key creation, model configuration changes, and spend management. Once an attacker scrapes a master key from a public repo — and credential-harvesting bots scan GitHub pushes within seconds of commit — the rest of the chain is execution.

Attack Chain (Defender's View)

  1. Initial access — secret exposure (MITRE T1552.001 / T1593): Master key committed to a public GitHub repository inside a configuration file.
  2. Credential access (T1528 / T1552): Attacker leveraged platform access to steal GitHub tokens associated with the project's release infrastructure.
  3. Persistence / privilege escalation (T1078 — Valid Accounts): Stolen tokens granted write access to the release pipeline without triggering MFA or anomalous-login controls typical of interactive sessions.
  4. Supply chain compromise (T1195.002): A malicious version of the litellm PyPI package was published through the legitimate release pipeline, inheriting the project's trusted signing and distribution path.
  5. Downstream impact: Any environment that installed or upgraded to the malicious version executed attacker-controlled code — in contexts where LLM API keys, cloud credentials, and internal service tokens are present in memory and environment variables.

Affected Products and Exposure Surface

  • Package: litellm on PyPI (one of the most-installed LLM proxy libraries in the Python ecosystem)
  • Affected users: Any developer workstation, CI/CD pipeline, container build, or production service that installed the malicious package version during the exposure window
  • High-risk deployments: LiteLLM proxy servers holding multiple provider API keys; AI agent frameworks that auto-update dependencies; Docker builds that don't pin versions or hashes

Exploitation Status

This is confirmed active exploitation — not theoretical. The malicious package was published to PyPI and was installable by real users. LiteLLM has disclosed the incident publicly (see the reporting at The Hacker News). No CVE has been assigned to this incident as of publication; this is a supply chain compromise event, not a product vulnerability, so treat it as an IR event rather than a patch cycle.

Why This Pattern Matters in 2026

This is the third distinct pattern we have responded to this year where a leaked CI/CD or platform secret — not a memory corruption bug — was the entire intrusion. GitHub's public event firehose is monitored by automated scrapers that extract and validate credentials in under 60 seconds. If your secrets touch a public repo for even a single commit, assume compromise. Force-pushing or deleting the commit does not remediate it — the secret is already gone.

Detection & Response

The detections below target the two places defenders have visibility: (1) endpoints and build agents that may have executed the malicious package, and (2) signs of credential theft and release-pipeline abuse.

Sigma Rules

YAML
---
title: Suspicious LiteLLM Package Installation or Upgrade
id: 3f7a2c91-8d4e-4b6a-9f21-5c8e7a1b3d44
status: experimental
description: Detects pip installing or upgrading the litellm package on endpoints or build agents. During the disclosed supply chain compromise window, any litellm install/upgrade is a high-fidelity hunting pivot for potential malicious package execution. Tune to your exposure window.
references:
  - https://thehackernews.com/2026/10/leaked-litellm-master-key-let-attackers.html
  - https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/10/05
tags:
  - attack.initial_access
  - attack.t1195.002
logsource:
  category: process_creation
  product: linux
detection:
  selection:
    Image|endswith:
      - '/pip'
      - '/pip3'
      - '/uv'
      - '/poetry'
      - '/pipx'
    CommandLine|contains:
      - 'litellm'
  filter_install_only:
    CommandLine|contains:
      - 'install'
      - 'upgrade'
      - 'add '
      - 'sync'
  condition: selection and filter_install_only
falsepositives:
  - Legitimate developer and CI installs after the malicious version was yanked and the window has closed
level: high
---
title: Python Process Accessing Cloud or LLM Credential Files
id: 8b1e4d52-6c3a-4f87-b2d9-7e5f1a9c2e66
status: experimental
description: Detects python/pip child processes reading cloud credential stores or SSH keys shortly after package operations. A malicious PyPI package executing credential harvesting would commonly enumerate ~/.aws, ~/.config/gcloud, ~/.azure, and ~/.ssh from a python interpreter context.
references:
  - https://thehackernews.com/2026/10/leaked-litellm-master-key-let-attackers.html
  - https://attack.mitre.org/techniques/T1552/001/
author: Security Arsenal
date: 2026/10/05
tags:
  - attack.credential_access
  - attack.t1552.001
logsource:
  category: process_creation
  product: linux
detection:
  selection:
    ParentImage|endswith:
      - '/python'
      - '/python3'
      - '/pip'
      - '/pip3'
    CommandLine|contains:
      - '/.aws/credentials'
      - '/.aws/config'
      - '/.config/gcloud'
      - '/.azure/'
      - '/.ssh/id_'
      - '.pypirc'
      - '/.git-credentials'
  condition: selection
falsepositives:
  - Legitimate SDK bootstrap scripts in developer environments (uncommon as pip-spawned children)
level: high
---
title: Outbound Connection from Python Interpreter to Pastebin or Exfil Endpoints
id: c4d9e7a1-2f5b-48c6-a3e8-9d1f6b4a7c22
status: experimental
description: Detects python processes making network connections to commonly abused exfiltration and dead-drop services. Malicious packages frequently beacon stolen environment variables and tokens to webhook-style endpoints during installation or first import.
references:
  - https://attack.mitre.org/techniques/T1567/002/
author: Security Arsenal
date: 2026/10/05
tags:
  - attack.exfiltration
  - attack.t1567.002
logsource:
  category: network_connection
  product: linux
detection:
  selection:
    Image|endswith:
      - '/python'
      - '/python3'
    DestinationHostname|contains:
      - 'webhook.site'
      - 'requestbin'
      - 'pipedream.net'
      - 'ngrok.io'
      - 'ngrok-free.app'
      - 'oastify.com'
      - 'interactsh.com'
  condition: selection
falsepositives:
  - Security researchers and sanctioned testing tooling
level: high

KQL — Microsoft Sentinel / Defender

This query hunts for litellm package installations across managed endpoints and build agents, then pivots to identify hosts where a Python interpreter accessed credential files or made unusual outbound connections within a 6-hour window — the behavioral signature of a poisoned package executing post-install theft.

KQL — Microsoft Sentinel / Defender
let Lookback = 30d;
let SuspiciousInstalls = DeviceProcessEvents
| where TimeGenerated > ago(Lookback)
| where (FileName in~ ("pip", "pip3", "uv", "poetry", "pipx") or ProcessCommandLine has_any ("pip install", "pip3 install", "uv pip", "poetry add"))
| where ProcessCommandLine has "litellm"
| project InstallTime=TimeGenerated, DeviceId, DeviceName, AccountName, ProcessCommandLine;
SuspiciousInstalls
| join kind=leftouter (
    DeviceProcessEvents
    | where TimeGenerated > ago(Lookback)
    | where FileName startswith "python"
    | where ProcessCommandLine has_any ("/.aws/", "/.azure/", "/.config/gcloud", "/.ssh/id_", ".pypirc", ".git-credentials", "env", "OPENAI_API_KEY", "ANTHROPIC_API_KEY", "AZURE_OPENAI")
    | project CredAccessTime=TimeGenerated, DeviceId, FileName, CredCommand=ProcessCommandLine
) on DeviceId
| where CredAccessTime between (InstallTime .. (InstallTime + 6h))
| project InstallTime, DeviceName, AccountName, ProcessCommandLine, CredAccessTime, FileName, CredCommand
| sort by InstallTime desc

For environments ingesting firewall/proxy or Sysmon network data into Sentinel, add this exfiltration pivot:

KQL — Microsoft Sentinel / Defender
let Lookback = 30d;
DeviceNetworkEvents
| where TimeGenerated > ago(Lookback)
| where InitiatingProcessFileName startswith "python" or InitiatingProcessFileName in~ ("pip", "pip3", "uv")
| where RemoteUrl has_any ("webhook.site", "pipedream.net", "ngrok.io", "ngrok-free.app", "oastify.com", "interactsh.com", "requestbin")
   or (RemoteIPType == "Public" and RemoteUrl !has_any ("pypi.org", "files.pythonhosted.org", "github.com", "githubusercontent.com", "api.openai.com", "api.anthropic.com", "openai.azure.com"))
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Connections=count(), Targets=make_set(RemoteUrl, 20) by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine
| sort by Connections desc

Velociraptor VQL

Use this artifact to sweep your fleet for hosts that have litellm installed, identify the installed version, and flag package integrity anomalies (unexpected files in the package directory — a common tamper indicator when a malicious release ships extra modules).

VQL — Velociraptor
-- Hunt: LiteLLM package presence, version, and anomalous payload files
-- Deploy across developer workstations, CI runners, and production Linux/Windows hosts

SELECT * FROM foreach(
    row={
        SELECT FullPath AS SitePackagesDir
        FROM glob(globs=['/**/site-packages/litellm', '/**/site-packages/litellm-*', 'C:/**/Lib/site-packages/litellm*'])
    },
    query={
        SELECT SitePackagesDir,
               FullPath AS PackageFile,
               Size AS FileSize,
               Mtime AS Modified
        FROM glob(globs=SitePackagesDir + '/**')
        WHERE FileSize > 0
          AND (
              PackageFile =~ '(setup|install|_bootstrap|payload|update|helper)\\.(py|so|pyd)$'
              OR PackageFile =~ '\\\\.(so|dll|dylib)$'
              OR Modified > '2026-05-27'
          )
    })
VQL — Velociraptor
-- Hunt: Python processes spawned by package managers with network connections
-- Indicates a package executing code during/after install (post-install hook behavior)

SELECT Pid, Ppid, Name, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ 'python'
  AND CommandLine =~ '(install|setup|litellm)'
UNION
SELECT Pid, Ppid, Name, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ '(pip|pip3|uv|poetry)'

Remediation Script

Run this on Linux/macOS hosts (and adapt paths for Windows build agents) to inventory litellm installations, check installed versions against a known-bad list you populate from the vendor advisory, and flag exposed credentials that must be rotated.

Bash / Shell
#!/bin/bash
# LiteLLM Supply Chain Compromise - Triage Script
# Security Arsenal - Incident Response
# Run as root or with sudo for full coverage

echo "=== LiteLLM Compromise Triage - $(date -u) ==="
echo ""

# 1. Locate all python environments with litellm installed
echo "[+] Searching for litellm installations..."
find / -type d -name "litellm*" -path "*site-packages*" 2>/dev/null | while read -r dir; do
    echo "  FOUND: $dir"
done

# 2. Report installed versions across all pip environments
echo ""
echo "[+] Enumerating installed litellm versions..."
for pybin in $(which -a python3 python 2>/dev/null | sort -u); do
    ver=$("$pybin" -m pip show litellm 2>/dev/null | grep -i "^Version" | awk '{print $2}')
    if [ -n "$ver" ]; then
        echo "  $pybin -> litellm $ver"
        # ACTION: Compare $ver against the malicious version(s) published in the
        # official LiteLLM advisory. If matched, treat host as compromised.
    fi
done

# 3. Check pip download/install logs for the exposure window
echo ""
echo "[+] Checking shell histories for litellm installs since 2026-05-27..."
grep -rEH "pip.*(install|upgrade).*litellm" /home/*/.bash_history /root/.bash_history 2>/dev/null

# 4. Inventory high-value secrets that must be rotated if a bad version is found
echo ""
echo "[+] Checking for exposed LLM/cloud credentials in environment files..."
find / -maxdepth 4 -name ".env" 2>/dev/null | while read -r envf; do
    if grep -qE "(OPENAI|ANTHROPIC|AZURE_OPENAI|AWS_SECRET|GOOGLE_APPLICATION)" "$envf" 2>/dev/null; then
        echo "  ROTATE CREDS referenced in: $envf"
    fi
done
ls -la /home/*/.aws/credentials /root/.aws/credentials 2>/dev/null

echo ""
echo "=== Triage complete. If a malicious version was found: isolate host, rotate ALL credentials present, and begin IR. ==="

Remediation

Immediate Actions (First 24 Hours)

  1. Determine exposure. Query your artifact repositories (Artifactory, Nexus, proxy caches), CI/CD build logs, and endpoint telemetry for any litellm install/upgrade since May 27, 2026 and specifically during the window the malicious version was live on PyPI. Check the official LiteLLM advisory and GitHub security disclosures for the exact malicious version number(s) and the clean version to pin to.
  2. Remove the malicious package. Uninstall the affected version and reinstall the known-good release with hash pinning:
Bash / Shell
# Uninstall, purge cache, reinstall pinned clean version with hash verification
pip uninstall litellm -y
pip cache purge
pip install litellm==<CLEAN_VERSION> --require-hashes
  1. Rotate everything the package could have touched. This is the painful but non-negotiable step. On any host that executed the malicious package, rotate: all LLM provider API keys (OpenAI, Anthropic, Azure OpenAI, Gemini, etc.), cloud IAM credentials (AWS access keys, Azure service principals, GCP service account keys), GitHub tokens, PyPI tokens, SSH keys, and any secrets present in environment variables or .env files on that host. A supply chain package executes with the full privilege of the installing user — in a CI runner, that often means production-deploy credentials.
  2. Rebuild affected artifacts. Any container image, lambda layer, or deployment artifact built during the exposure window that contains litellm must be rebuilt from a clean base and redeployed. Do not attempt in-place remediation of images.

If You Operate LiteLLM Proxy in Production

  • Rotate your LiteLLM master key immediately (LITELLM_MASTER_KEY / master_key in proxy config) and audit the proxy's virtual key inventory for unauthorized keys created during the window. Review proxy logs for admin API calls (/key/generate, /model/new, /config/update) from unexpected source IPs.
  • Restrict master key usage to a dedicated admin network path and never expose the proxy admin endpoints to the internet.

Preventive Controls (This Quarter)

  1. Deploy pre-commit secret scanning and push protection. Enable GitHub secret scanning with push protection on every repository — it blocks credential commits before they land. Augment with gitleaks or trufflehog in CI. A single leaked master key caused this entire incident.
  2. Never commit live credentials to any repository — public or private. Assume any committed secret is compromised within 60 seconds. Use OIDC-based short-lived credentials (GitHub Actions OIDC to AWS/Azure/GCP) instead of long-lived tokens wherever possible.
  3. Pin dependencies with hashes. Enforce pip install --require-hashes or use uv / poetry lockfiles with hash verification in all CI pipelines. Hash pinning defeats malicious version substitution even when the upstream index is compromised.
  4. Gate new package versions. Introduce a cooling-off period (e.g., 72 hours) before newly published dependency versions are permitted into production builds, plus internal artifact proxying so you control which versions are installable.
  5. Scope CI/CD tokens to least privilege. Release pipeline tokens should be environment-scoped, short-lived, and incapable of publishing outside their designated workflow. GitHub fine-grained PATs and environment protection rules materially reduce blast radius.
  6. Monitor your own dependency footprint. Use the detection content above as standing hunts, and subscribe to PyPI/GitHub advisory feeds for every package in your critical path — especially AI/LLM tooling, which has become a priority target for exactly this attack pattern in 2025–2026.

Vendor References

Monitor the official LiteLLM GitHub security advisories for the confirmed malicious version numbers and the vendor's recommended clean version — pin to that version explicitly once published.

Related Resources

Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.