Back to Intelligence

LiteLLM Supply Chain Attack via Trivy Compromise: 2,500+ Organizations Exposed — Detection and Remediation Guide

SA
Security Arsenal Team
August 12, 2026
11 min read

LiteLLM — the popular open-source Python library used to normalize API calls across dozens of large language model providers — has become the latest casualty in a cascading software supply chain attack. According to SecurityWeek, attackers leveraged the recent compromise of Trivy, Aqua Security's widely deployed vulnerability scanner, as a pivot point to compromise the LiteLLM project and push a malicious release to PyPI. Organizations that installed or upgraded the trojanized package received an information-stealing payload capable of harvesting credentials, environment variables, API keys, and cloud tokens. More than 2,500 organizations are believed to have pulled the poisoned version.

This is not a theoretical risk. LiteLLM sits at a uniquely privileged position in modern AI infrastructure: it is almost always deployed with a dense concentration of high-value secrets — OpenAI, Anthropic, Azure, AWS, and GCP API keys — frequently loaded directly into environment variables or configuration files adjacent to the library. An infostealer running inside a LiteLLM deployment is, functionally, a key to every LLM provider and cloud account the organization touches.

If your environment runs LiteLLM — directly, in Docker images, in CI/CD pipelines, or embedded in AI gateway/proxy deployments — you need to treat this as an active incident until proven otherwise.

Technical Analysis

What Happened

The attack chain is a textbook example of supply chain cascade compromise:

  1. Stage 1 — Trivy compromise: Attackers first compromised Trivy, the open-source vulnerability scanner from Aqua Security. Because Trivy is embedded in thousands of CI/CD pipelines, build systems, and developer workstations, this gave the attackers a broad initial footprint.
  2. Stage 2 — Pivot to LiteLLM: The Trivy foothold was abused to compromise the LiteLLM project's release pipeline, allowing the attackers to publish a trojanized version of the package to PyPI under the legitimate project name.
  3. Stage 3 — Downstream infection: Any organization running pip install litellm, pip install -U litellm, or building a container image without a pinned version during the exposure window received the malicious package. The malicious code executed an infostealer at install or import time.

Why LiteLLM Is a High-Value Target

LiteLLM deployments share several characteristics that make them ideal infostealer targets:

  • Secret-dense environments: LiteLLM proxy configurations routinely contain API keys for multiple LLM providers (OpenAI, Anthropic, Azure OpenAI, Google Vertex, AWS Bedrock) plus database connection strings and master keys for the proxy itself.
  • Cloud metadata access: Containerized LiteLLM deployments on AWS, GCP, and Azure can reach instance metadata services (169.254.169.254) to harvest temporary IAM credentials — a classic infostealer behavior in cloud environments.
  • CI/CD reach: Build agents that install LiteLLM during testing inherit pipeline secrets, signing keys, and deployment credentials.
  • Developer workstations: Engineers running LiteLLM locally expose SSH keys (~/.ssh/), cloud CLI credentials (~/.aws/credentials, ~/.config/gcloud/), browser stores, and .env files.

Infostealer Behavior Profile

Consistent with modern Python-delivered infostealers, defenders should assume the payload attempted to:

  • Enumerate and exfiltrate environment variables (where most LLM API keys live).
  • Read common credential locations: ~/.aws/credentials, ~/.ssh/, ~/.config/gcloud/, ~/.kube/config, .env files in the working directory tree.
  • Query cloud instance metadata endpoints for IAM tokens.
  • Exfiltrate over HTTPS to attacker-controlled infrastructure, often disguised as legitimate API or telemetry traffic.

Exploitation Status

This is confirmed active exploitation in the wild. The malicious package was live on PyPI and downloaded by thousands of organizations before removal. This is not a proof-of-concept scenario — if the trojanized version entered your environment, you should operate under a breach-assumption model: any secret accessible to a process running the malicious package must be considered compromised.

Detection & Response

The detections below target the observable behaviors of this campaign: installation of the malicious LiteLLM release, Python processes harvesting credential files, and suspicious outbound connections from Python/pip processes. Tune allowlists for your known package-build and deployment automation.

SIGMA Rules

YAML
---
title: Pip Installation of LiteLLM Without Version Pin
date: 2026/04/06
id: 8f2c1a94-3b7d-4e51-9c2a-6d1e8f0b3a45
status: experimental
description: Detects pip installing or upgrading LiteLLM, which during the compromise window could have pulled the trojanized release. Review any unpinned installs during the exposure window as potentially malicious.
references:
  - https://www.securityweek.com/over-2500-organizations-impacted-by-litellm-supply-chain-attack/
  - https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
tags:
  - attack.initial_access
  - attack.t1195.002
logsource:
  category: process_creation
  product: linux
detection:
  selection_img:
    Image|endswith:
      - '/pip'
      - '/pip3'
      - '/python'
      - '/python3'
      - '/uv'
  selection_cli:
    CommandLine|contains:
      - 'install litellm'
      - 'install -U litellm'
      - 'install --upgrade litellm'
      - 'litellm=='
      - 'litellm>='
  condition: selection_img and selection_cli
falsepositives:
  - Legitimate developer installs after the malicious version was yanked — correlate with install date against the compromise window
level: high
---
title: Python Process Accessing Cloud and SSH Credential Stores
date: 2026/04/06
id: 2b7e9d31-5c48-4f62-a91d-0e4c7b2f8d16
status: experimental
description: Detects Python or pip child processes accessing credential files commonly targeted by infostealers, including AWS credentials, SSH keys, GCP config, and Kubernetes configs. Consistent with the LiteLLM supply chain infostealer behavior.
references:
  - https://www.securityweek.com/over-2500-organizations-impacted-by-litellm-supply-chain-attack/
  - https://attack.mitre.org/techniques/T1552/
  - https://attack.mitre.org/techniques/T1552.004/
author: Security Arsenal
tags:
  - attack.credential_access
  - attack.t1552
  - attack.t1552.004
logsource:
  category: file_event
  product: linux
detection:
  selection_target:
    TargetFilename|contains:
      - '/.aws/credentials'
      - '/.aws/config'
      - '/.ssh/id_rsa'
      - '/.ssh/id_ed25519'
      - '/.config/gcloud/'
      - '/.kube/config'
      - '/.azure/'
      - '/.docker/config.json'
  selection_img:
    Image|endswith:
      - '/python'
      - '/python3'
      - '/pip'
      - '/pip3'
  condition: selection_target and selection_img
falsepositives:
  - Legitimate boto3/gcloud SDK usage by application code — baseline known AI/ML workloads and alert on deviations
level: high
---
title: Python Process Querying Cloud Instance Metadata Service
date: 2026/04/06
id: 5d1a8c47-9e63-4b28-bf05-3c7d2e91a084
status: experimental
description: Detects Python processes connecting to the cloud instance metadata service (169.254.169.254), a hallmark of IAM credential theft by infostealers in containerized and cloud VM environments.
references:
  - https://www.securityweek.com/over-2500-organizations-impacted-by-litellm-supply-chain-attack/
  - https://attack.mitre.org/techniques/T1552.005/
author: Security Arsenal
tags:
  - attack.credential_access
  - attack.t1552.005
logsource:
  category: network_connection
  product: linux
detection:
  selection:
    DestinationIp:
      - '169.254.169.254'
      - 'fd00:ec2::254'
    Image|endswith:
      - '/python'
      - '/python3'
  condition: selection
falsepositives:
  - Legitimate SDK metadata calls from applications using instance roles — alert on hosts where LiteLLM or unreviewed Python packages were recently installed
level: medium

KQL Hunt — Microsoft Sentinel / Defender

The following query hunts across process execution and network telemetry for pip-based LiteLLM installs, Python processes accessing credential stores, and suspicious outbound connections from Python processes. It works against both Defender for Endpoint tables (DeviceProcessEvents, DeviceNetworkEvents) and Syslog-ingested Linux telemetry.

KQL — Microsoft Sentinel / Defender
let Lookback = 30d;
// Part 1: Find hosts that installed or upgraded litellm via pip/uv
let LitellmInstalls = union isfuzzy=true
    (DeviceProcessEvents
    | where TimeGenerated > ago(Lookback)
    | where ProcessCommandLine has_any ("install litellm", "install -U litellm", "install --upgrade litellm", "litellm==", "litellm>=")
    | project InstallTime=TimeGenerated, DeviceName, AccountName, ProcessCommandLine, ReportId),
    (Syslog
    | where TimeGenerated > ago(Lookback)
    | where SyslogMessage has_any ("install litellm", "install -U litellm", "litellm==")
    | project InstallTime=TimeGenerated, DeviceName=Computer, AccountName=HostIP, ProcessCommandLine=SyslogMessage, ReportId=0);
// Part 2: On those same hosts, look for Python processes touching credential paths or metadata service
let CredAccess = DeviceProcessEvents
| where TimeGenerated > ago(Lookback)
| where ProcessCommandLine has_any (".aws/credentials", ".ssh/id_", ".kube/config", "gcloud", ".env")
| where FileName in~ ("python", "python3", "pip", "pip3")
| project CredTime=TimeGenerated, DeviceName, CredCommand=ProcessCommandLine;
let MetadataAccess = DeviceNetworkEvents
| where TimeGenerated > ago(Lookback)
| where RemoteIP == "169.254.169.254"
| where InitiatingProcessFileName in~ ("python", "python3")
| project MetaTime=TimeGenerated, DeviceName, InitiatingProcessCommandLine;
LitellmInstalls
| join kind=leftouter CredAccess on DeviceName
| join kind=leftouter MetadataAccess on DeviceName
| where isnotempty(CredCommand) or isnotempty(InitiatingProcessCommandLine)
| project InstallTime, DeviceName, AccountName, ProcessCommandLine, CredTime, CredCommand, MetaTime, InitiatingProcessCommandLine
| order by InstallTime desc

If the join returns no rows, run the LitellmInstalls portion standalone to at least enumerate every host that touched LiteLLM during the window — those hosts need manual triage regardless of whether post-install credential access was captured.

Velociraptor VQL Hunt

Use this artifact to sweep endpoints for Python processes accessing credential stores or holding connections to the metadata service — the strongest host-level indicators of the infostealer's execution.

VQL — Velociraptor
-- LiteLLM supply chain infostealer hunt:
-- Python processes with command lines referencing credential paths,
-- plus live connections to cloud metadata endpoints
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE (Name =~ '(?i)python|pip'
   AND CommandLine =~ '(?i)\.aws/credentials|\.ssh/id_|\.kube/config|gcloud|169\.254\.169\.254|\.env')
   OR Exe =~ '(?i)litellm'

-- Correlate with active network connections from Python processes
SELECT Pid, Name, CommandLine,
       net.LocalAddr.IP AS LocalIP, net.LocalAddr.Port AS LocalPort,
       net.RemoteAddr.IP AS RemoteIP, net.RemoteAddr.Port AS RemotePort,
       net.Status AS ConnStatus
FROM netstat()
WHERE Name =~ '(?i)python'
  AND net.Status =~ 'ESTABLISHED'
  AND NOT net.RemoteAddr.IP =~ '^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)'

The second statement surfaces established external connections from any Python process — expect noise from legitimate LLM API traffic (api.openai.com, etc.), so enrich RemoteIP against your known-good LLM provider allowlist. Unknown destinations from a host that installed LiteLLM during the exposure window warrant immediate isolation and triage.

Remediation and Verification Script

Run this on Linux hosts, containers, and build agents to identify installed LiteLLM versions, locate it inside container images, and check for the common indicators left behind by the install event.

Bash / Shell
#!/bin/bash
# LiteLLM supply chain compromise — verification and triage script
# Run on endpoints, build agents, and container hosts.

echo "=== [1] Checking installed litellm version across pip environments ==="
for PYBIN in python3 python; do
  if command -v $PYBIN >/dev/null 2>&1; then
    $PYBIN -m pip show litellm 2>/dev/null | grep -E '^(Name|Version|Location)'
  fi
done

echo ""
echo "=== [2] Scanning pip caches and site-packages for litellm artifacts ==="
find / -type d -name 'litellm*' 2>/dev/null \
  -path '*/site-packages/*' -o -path '*/.cache/pip/*' 2>/dev/null | head -50

echo ""
echo "=== [3] Checking pip install history in logs (if available) ==="
grep -rih 'litellm' /var/log/apt/ /var/log/dnf* /var/log/yum* ~/.cache/pip/log* 2>/dev/null | tail -20

echo ""
echo "=== [4] Container image check (docker) ==="
if command -v docker >/dev/null 2>&1; then
  docker images --format '{{.Repository}}:{{.Tag}}' | while read -r img; do
    if docker run --rm --entrypoint sh "$img" -c 'pip show litellm 2>/dev/null' 2>/dev/null | grep -q 'Version'; then
      echo "FOUND litellm in image: $img"
      docker run --rm --entrypoint sh "$img" -c 'pip show litellm 2>/dev/null | grep Version'
    fi
  done
fi

echo ""
echo "=== [5] Searching for .env and credential files readable by python service users ==="
find /opt /srv /home /app -maxdepth 4 -name '.env' -readable 2>/dev/null | head -20

echo ""
echo "=== [6] Recent outbound HTTPS from python processes (audit log) ==="
ausearch -k network_outbound 2>/dev/null | grep -i python | tail -20 || \
  echo "No auditd key configured — enable syscall auditing for python egress going forward."

echo ""
echo "=== DONE. If litellm was installed during the compromise window, treat secrets as exposed. ==="

Remediation

Treat any host, container, or pipeline that installed LiteLLM during the exposure window as compromised until proven otherwise. The remediation priority order matters — credentials first, cleanup second.

  1. Rotate all exposed secrets immediately. Every API key, token, and credential accessible to a process running the malicious package must be revoked and reissued. Prioritize: LLM provider keys (OpenAI, Anthropic, Azure OpenAI, Google, AWS Bedrock), LiteLLM proxy master keys and database credentials, cloud IAM credentials (including instance-role-derived temporary credentials, which require reviewing CloudTrail/Azure Activity Log for use), SSH keys, and CI/CD pipeline secrets.
  2. Identify and pin your package versions. Inventory every environment with LiteLLM installed — including transitive dependencies in AI gateway products, LangChain-based apps, and container base images. Pin litellm==<known-good-version> in requirements.txt and lockfiles, and rebuild affected images from scratch rather than patching in place.
  3. Purge caches. Malicious wheels can persist in pip caches (~/.cache/pip), private PyPI mirrors/proxies (Artifactory, Nexus, devpi), and container layer caches. Invalidate all of them. Your internal mirror is a re-infection vector if it cached the trojanized wheel.
  4. Hunt before you trust. Run the Sigma, KQL, and VQL detections above across the full exposure window. Absence of a detection hit does not equal absence of compromise if logging gaps exist — check your Python egress and file auditing coverage.
  5. Review egress from AI workloads. LiteLLM proxies should only be talking to a small, enumerable set of LLM provider endpoints. Implement egress allowlisting for AI infrastructure; any other destination from a LiteLLM process is anomalous by definition.
  6. Assess your Trivy exposure in parallel. Because the LiteLLM compromise originated from the Trivy hack, apply Aqua's remediation guidance for the Trivy incident: rotate credentials available to CI jobs running Trivy, verify the integrity of Trivy binaries and DB updates in your pipelines, and pin Trivy to a verified release.
  7. Harden the pipeline structurally. Require hash-pinned dependencies (pip install --require-hashes), enable Sigstore/cosign verification where available, deploy private PyPI proxies that quarantine new package versions for a bake-in period, and gate production deploys on software composition analysis of the final artifact — not just the source repo.

Monitor the LiteLLM GitHub repository and PyPI project page for the project's official incident advisory and the list of known-good versions, and check CISA and Aqua Security's advisories for updates on the upstream Trivy compromise. Given the scale — 2,500+ organizations — expect follow-on activity as attackers monetize the harvested LLM API keys and cloud credentials. Key rotation this week is not optional.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

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