🔍AI RiskAtlas
← Real-world cases
Case study

TeamPCP poisons the LiteLLM AI gateway on PyPI to harvest LLM API keys

Real-world incident24 Mar 2026🗺️ Model / Package Supply Chain

As part of a multi-ecosystem supply-chain cascade (Trivy onward), TeamPCP used stolen PyPI publishing tokens to ship backdoored BerriAI LiteLLM versions whose auto-running .pth payload harvested cloud, SSH and Kubernetes secrets plus env vars holding OPENAI_API_KEY/ANTHROPIC_API_KEY — exfiltrating to a typosquatted C2; AI-talent firm Mercor was a downstream victim, with Lapsus$ claiming ~4TB stolen.

Root cause — why it happened

Lots of AI apps don't talk to each LLM provider directly — they route everything through a shared 'gateway' library that holds all the provider keys in one place. The popular open-source gateway here is LiteLLM, installed from the public Python package index (PyPI). Attackers stole the credentials that let someone publish new versions of LiteLLM, then quietly shipped two booby-trapped releases. One of them dropped a special file (a `.pth` file) that Python runs automatically the moment any Python program starts — so you didn't even have to use LiteLLM for the trap to spring. Once it ran, it grabbed every secret it could find on the machine — cloud passwords, server keys, and all the LLM API keys sitting in environment variables — encrypted them, and shipped them off to a lookalike attacker website. Because the gateway layer is exactly where all the keys live together, one poisoned package handed the attacker the whole key ring at once.

Risks this case illustrates

Named in the standard (OWASP/ATLAS/NIST) lens. Click a highlighted component in the diagram below to see which risks attach where.

How it unfolded

Untrusted supply chainYour infrastructureuploads artefactstolen tokens publish backdoored 1.82.7 / 1.82.8🌐Publisher(maybe🏪Model / PackageRegistry🧬Downloadedmodel / package🏗️Your build /serving stack🧠Your deployedmodel🌐TeamPCP (stolenPyPI tokens)🧬Host secrets(env vars,🌐C2:models[.]litellm[.]cloud
InstructionsDataActionsControl / decisionFeedback / logs
👆 Click a component to inspect its risks
SetupStep 1 / 6

Stolen publishing tokens reach PyPI

The attackers didn't break into LiteLLM's code so much as steal the keys that let someone publish new versions of it. Per the researchers, those publishing tokens were picked up in an earlier break-in of a different security tool (Trivy), then reused here. With the keys in hand, the attacker can upload a new 'LiteLLM' that the whole world will trust, because it comes from the real package's name.

📝Backdoored releases published (illustrative)log
pypi: berriai/litellm
  publisher token: STOLEN (reportedly via earlier Trivy compromise)
  1.82.7  -> malicious code injected into proxy_server module
  1.82.8  -> ships litellm_init.pth inside the wheel
  package name/owner: UNCHANGED (consumers see nothing odd)
  C2 domain registered ~1 day before the attack
Step 1 / 6

Controls & guardrails — what would have stopped it

Three things would have blunted this. First, don't trust a package by name alone — lock each dependency to an exact, reviewed version and check its fingerprint, so a backdoored release the attacker pushes with stolen keys doesn't match and won't install. Second, don't keep all your keys in one easy-to-grab pile next to the gateway — hand them out only when needed and for a short time, so a snoop on the machine finds little. Third, control where the machine can phone home: if it can only reach approved addresses, the secret-stuffed message to the lookalike attacker site gets blocked. The honest catch: pinning only helps if you review before you bump the version, and a determined attacker can still route data through somewhere you already allow.

Preventive
  • Weight provenance, hashing & pre-deploy evals

    Hashes prove the file is unchanged, not that it's safe — a trained-in backdoor or ablated refusal direction passes integrity checks. Only behavioural evals probe disposition, and they can't be exhaustive.

  • Serving-stack & provisioning attestation, cache isolation

    Attestation is operationally heavy and rarely covers the full stack; cache isolation trades away latency/cost savings, so it's often left on for performance. Signing proves a template wasn't tampered in transit, not that a signed template is benign — an insider with signing rights still needs review and trigger-focused evals.

  • Least-privilege identity & scoped credentials

    Doesn't prevent manipulation — only caps its reach. Hard to get right operationally; over-broad scopes are the common real-world failure.

  • Egress allowlisting & DLP on tool arguments

    Allowlists fight an open-ended channel; legitimate-but-broad destinations (any URL fetch, any email) are hard to constrain without breaking usefulness. Encoding can evade naive DLP.

Detective
  • Runtime monitoring & anomaly detection

    Detects the anomalous, not the novel-but-subtle; high false-positive rates cause alert fatigue. Always a step behind a sufficiently quiet attacker.

  • Full-trace audit logging

    Logging is forensic, not preventive — it explains harm after the fact. Useless if no one reviews it or if the materialised context isn't captured.

Corrective
  • Governance: risk assessment, red-teaming & incident response

    Process reduces likelihood and speeds recovery but executes no technical control itself; weak follow-through makes it theatre.

  • Loop/cost circuit-breakers & consistency checks

    Thresholds are blunt — too tight breaks legitimate long tasks, too loose lets damage accrue first. Catches runaway dynamics, not a single well-formed bad decision.

Lessons

  • The AI-gateway/proxy layer is uniquely high-value collateral: it concentrates multi-provider LLM keys alongside cloud and cluster credentials, so one compromised dependency there harvests the whole secret estate at once.
  • Trust the artifact, not the name: a stolen publishing token lets an attacker ship a backdoor under a trusted package name — pin to reviewed versions and verify hashes/signatures on every install rather than resolving by name/tag.
  • Installing a package can run code at startup, not just on import: a `.pth` file executes on essentially any Python process on the host, a far broader trigger than `import litellm` — scan dependencies for unexpected `.pth`/post-install hooks.
  • Treat LLM API keys as crown-jewel secrets: keep them out of long-lived plaintext environment variables, issue short-lived scoped tokens from a broker, and monitor for anomalous spend/egress that signals key theft.
  • Behavioural evals can't catch this — there is no model behaviour to test; the compromise lives in the install and runtime, so the controls are supply-chain hygiene, secrets isolation, and deny-by-default egress.
  • Supply-chain attacks cascade across ecosystems: tokens stolen from one tool (reportedly Trivy) were reused to poison another (LiteLLM) — assume a single credential theft can pivot into your dependencies.

Proposals & gaps this case surfaced

Non-destructive suggestions for the library — proposed, not adopted.

★ proposed sub-riskAI-gateway / proxy secret concentrationunder #8

A shared LLM gateway/proxy or aggregation layer concentrates many providers' API keys — often alongside cloud and cluster credentials — in one process/host environment, so a single compromise of that layer (a poisoned dependency, an exposed endpoint, or a leaked image) exposes the organisation's entire AI key estate and adjacent secrets at once.

✚ proposed guardrailBroker LLM/cloud secrets out of the gateway process: short-lived scoped tokens + per-provider spend/egress monitoringAgent Access & Tool Control

Do not store long-lived multi-provider LLM keys (or ambient cloud/K8s credentials) in the gateway/proxy's plaintext process environment. Issue short-lived, scoped tokens from a secret broker at request time, isolate the serving stack from host cloud/cluster credentials, and monitor per-provider spend and egress so a stolen key surfaces as anomalous usage — capping the loot a compromised gateway dependency can harvest.

This case shows a gap: we treat 'don't run poisoned packages' as the lesson, but the reason it hurt so much is that ALL the AI keys lived in one easy-to-grab place. Keeping keys spread out and short-lived deserves to be its own safeguard, not an afterthought.

These surface as proposals across the Control Library and Risk Taxonomy; adopt them by hand when ready.

Sources

Practise the risk class — related scenarios

📧The Email That Gave Orders

A support email hides instructions — and the assistant obeys them

🗄️When the Query Bites Back

A text-to-SQL agent runs the model's output straight at the database

👂Overheard Through the Cache

A speed optimisation becomes a cross-tenant listening device

🏭Poisoning the Agent Factory

Compromise the pipeline that builds agents, and every new worker is born malicious

🪟Stealing the Model

Two doors to the same secret: reconstruct the model through its API, or just walk off with the weight file

🪤The Bug Report That Ran Code

A fake Sentry error report hijacks a developer's coding agent into running a shell command

🚪The Classifier That Waves It Through

The safety guard is itself a trained model — and someone poisoned its lessons

📼The Compromised Flight Recorder

The forensic record is itself the attack surface — an agent's log is poisoned, then quietly rewritten

🔓The Model That Forgot to Say No

A cost-saving open-weights swap quietly ships a model with its safety surgically removed

🖼️The Picture That Whispered

A screenshot that's harmless at full size becomes an order once the system shrinks it

💤The Sleeper

A capable third-party model that behaves perfectly — until it sees the trigger

🎫The Stolen Session

An attacker captures the agent's bearer token — and inherits its authority

🔌The Tool With a Hidden Agenda

A trusted MCP email tool quietly BCCs every message to an attacker

🥸The Uninvited Agent

A forged peer registers on the agent directory — and the planner enlists it

🖼️Zero-Click Leak by Picture

An inbox summary quietly ships a secret to an attacker's server

AI RiskAtlas is an educational model of how GenAI & agentic systems work and fail. Architectures and payloads are illustrative and simplified for learning — not operational guidance. Real-world cases are summarised from public reporting.

Sources & further reading →·Built by Shi Yuan ↗