Hero image for: LiteLLM on PyPI: Backdoored Builds, Secret Harvest, and .pth Persistence

LiteLLM on PyPI: Backdoored Builds, Secret Harvest, and .pth Persistence


TLDR

SignalStack Tech Report · March 26, 2026 · Security / Supply Chain / Python

Why this is on SignalStack: we prioritize incidents where attack mechanics change what developers must verify—import-time execution, PyPI compromise, and host-level persistence—not only the headline package name.

LiteLLM—a widely used Python library for calling many LLM APIs from one interface—was compromised on PyPI when malicious package versions (1.82.7 and 1.82.8) shipped code that steals secrets and, in the later build, persists across Python startups via a .pth hook.

  • Affected builds (reported): 1.82.7 and 1.82.8 on PyPI
  • Risk: broad secret harvest (cloud, CI, k8s, keys, env) plus dropper / persistence behavior described in incident analyses
  • Do now: pin or downgrade to a maintainer-confirmed clean release, rotate credentials, hunt for stray .pth files under site-packages (or recreate the venv), then inspect hosts for persistence and lateral movement
  • Key risk: LiteLLM aggregates many provider keys—one bad install is a single high-yield compromise; pair with digest pinning and lockfiles (see Context & primary sources)

Treat attribution (e.g., to named threat groups), infection counts, and geopolitical add-ons as provisional unless your own forensics confirm them.

Diagram suggesting data exfiltration from developer and cloud environments

AI-facing Python deps often sit where many provider keys meet one import path—high leverage for stealers.

What happened

On March 24, malicious LiteLLM builds appeared on PyPI. The project tracker and security advisories coalesced around versions 1.82.7 and 1.82.8 as the bad releases.

Early public reports—including a researcher who reported severe disruption after pulling the package—helped surface the issue quickly. Community and vendor analysis described malicious logic embedded so it could run on import, with initial placement reported under paths such as litellm/proxy/proxyserver.py.

Version 1.82.8 was described as adding stronger persistence: a .pth (path configuration) file under site-packages. On startup, CPython’s site module processes .pth entries: in addition to extending sys.path, lines that act as import hooks can run during interpreter initialization—before your app imports anything. The payload is not limited to “when you import litellm”; it is interpreter-wide: other scripts, one-off tools, and jobs on the same environment can still trigger the hook. In incident terms, that is host-level persistence in the Python layer, not a self-contained library bug.

Incident responders labeled the payload as a credential stealer / dropper variant (names like “Cloud Stealer” appear in analyses) aimed at developer and cloud estates: SSH keys, cloud tokens (e.g. AWS, GCP, Azure), Kubernetes material, .env and environment variables, DB and TLS keys, CI/CD secrets, and crypto wallet data. Some descriptions also mention downloaded follow-on payloads and Kubernetes-oriented behavior; treat operational detail as variable by environment, not uniform across every install.

PyPI subsequently removed the malicious releases; maintainer guidance pointed to 1.82.6 (or another maintainer-confirmed clean line) as the latest safe version at the time of remediation—verify against upstream release notes before pinning.

Commentary also ties the episode to a broader pattern of supply-chain hits on dev tooling (other ecosystems and products get named in reports); overlap with prior incidents is often framed as a reminder to rotate credentials completely after any suspected compromise.

Why it matters

LiteLLM sits on a high-value path: it often wraps API keys, routing config, and environment secrets for AI workloads. One bad `pip install` can exfiltrate the keys to the kingdom without touching your model vendor directly.

This case is a clean example of why supply-chain risk scales: popular abstraction layers for AI are as attractive as core cloud SDKs—sometimes more, because they aggregate many providers behind one dependency.

Single point of compromise: convenience layers that normalize OpenAI, Anthropic, Azure, Bedrock, and more into one config surface also concentrate env files, tokens, and routing keys for an attacker. Mitigations are structural: split secrets by least privilege where feasible, pin digests in lockfiles, and verify packages against maintainer-owned sources—not only “latest semver feels fine.”

Persistence tricks (here, .pth) turn a bad version into a host incident: pip uninstall may remove the wheel but leave a stray .pth that still runs at startup—treat cleanup as artifact hunting or a full venv rebuild, not a single command.

Unconfirmed metrics (e.g., very large exfiltration counts) sometimes appear in informal reports; use them for severity intuition, not audit-grade claims, unless independently validated.

Key details at a glance

AreaDetailNote
PackageLiteLLM on PyPIHigh-value path for LLM API config
Bad versions1.82.7, 1.82.8 (reported)Confirm with maintainer issue / advisories
ExecutionOn-import malicious logicBypasses “unused import” assumptions
Persistence.pth under site-packages (interpreter startup)Not limited to import litellm
Targets (per analyses)SSH, cloud IAM, k8s, env, CI, DB/TLS, walletsRotate broadly if exposed
RegistryMalicious wheels yankedDoes not remediate already-installed hosts
AttributionNames in some reportsSeparate from mechanical takedown facts

Supply chain compromise spreading across dependencies

One poisoned abstraction layer can fan out across laptops, CI, and shared runners—treat installs as fleet events.

Some reports mention hundreds of thousands of exfiltration events or related scale metrics; treat as unverified unless your SOC or vendor confirms.

If your org touched the bad builds, assume secrets are burned until rotated: API keys, cloud IAM, CI tokens, kube credentials, SSH, database passwords, signing keys.

What to watch next

  1. BerriAI postmortem — Exact version matrix, IOC lists, and hardening (yanking alone does not fix already-installed wheels).
  2. Artifact cleanup — After uninstall, enumerate site-packages for unknown .pth files and suspicious easy-install.pth or third-party path hacks; when in doubt, burn the venv and reinstall from pinned, verified wheels.
  3. Reproducible installs — Digest pinning / lockfiles (e.g. pip-tools with --generate-hashes, pip install --require-hashes, Poetry lock, uv.lock), private mirrors, CI integrity checks; treat “AI stack” jobs like production deploys.
  4. Credential lifecycle — Atomic rotation after any supply-chain scare—partial rotation is how cascade stories repeat.
  5. Cross-ecosystem IOCs — Map overlaps from PyPI / npm campaigns to your SBOM.
  6. Downstream risk — Customer and regulatory questions if AI pipelines had broad API access from compromised dev laptops or CI.

The SignalStack angle

What we are not doing: treating this as a “Python-only” footnote. What we are doing: naming repeatable controls—verify releases against trusted sources, hunt .pth and other persistence, rotate as if keys already left the building.

1. AI abstraction layers are high-value targets

LiteLLM sits where API keys and environment configuration converge. SignalStack’s read: the same dependency graph that speeds shipping concentrates secrets for an attacker.

2. Persistence turns a library incident into a host incident

Uninstall alone may not remove .pth artifacts. Closing metric: time to identify a clean interpreter state on every affected runner.

Disclaimer: Verify versions and remediation steps against primary maintainer and registry advisories.

Context & primary sources

Machine-readable records and standards language—enough to brief AppSec without diluting the incident story.

  • Advisory index — GitHub: GitHub Advisory Database (search LiteLLM / GHSA as advisories are filed).
  • Registry operations — PyPI support: pypa/pypi-support issues — public queue for takedowns and package problems (incident paper trail often surfaces here).
  • Python mechanism — site / .pth: Python docs — site module — how path configuration files participate in startup (ground truth for persistence discussions).
  • Supply-chain patterns — independent analysis: Snyk blog — recurring PyPI malware patterns (use search; not LiteLLM-specific).
  • Component assurance — OWASP SCVS: OWASP Software Component Verification Standard — vocabulary for dependency verification programs.
  • Open source hygiene — OpenSSF Scorecard: scorecard.dev — signals for repo hygiene (complements, not replaces, digest pinning).

Bridge: pair the Python site docs with on-disk hunts; pair SCVS and Scorecard with procurement conversations.

FAQ

Q What is LiteLLM?

A A popular Python library that unifies calls to many LLM providers behind one API—so it often sees API keys and environment configuration.

Q Which PyPI versions were affected?

A Published reports and the maintainer issue thread center on 1.82.7 and 1.82.8. Confirm with the official issue / release notes on the repo you trust.

Q What should I do if I installed those versions?

A Install a maintainer-confirmed clean version (or downgrade to a known-good line), then rotate all potentially exposed secrets. pip uninstall alone may not remove a malicious .pth left under site-packages—manually inspect that tree (and user-site if used) for unfamiliar .pth files, or delete and recreate the venv or container layer from a trusted lockfile. Rebuild sensitive hosts or CI images if you cannot prove a clean interpreter state.

Q Why is “just uninstall LiteLLM” incomplete?

A Because .pth hooks can run at Python startup for any script sharing that environment—persistence is not scoped to importing the package. The malware may also have staged files outside the wheel.

Q Why is LiteLLM especially painful if compromised?

A It often centralizes many LLM provider credentials and routing configuration—one successful steal can dwarf “single API key” incidents. Segment keys, pin artifacts, and rotate as a set after suspicion.

Q Was this limited to pip install on a laptop?

A Risk extends to CI, containers, and shared runners that installed the package—anything that executed the code.

Q How do I verify scale or attribution claims?

A Prefer primary sources (maintainer postmortem, PyPI metadata, your own logs) over headline numbers from social or unnamed estimates.