Security1 distinct publisher2 min readPublished
Two litellm releases that never came out of the project's CI harvested SSH keys and cloud credentials from every host that installed them. litellm traces the entry point to the Trivy scanner in its own pipeline.
The Watch · Security desk

Compiled by The WatchSomething wrong?How this is made
A scanner in CI sits inside the release trust boundary. It runs with the build environment loaded, and in a Python project that environment is usually also where the PyPI publishing token lives. Compromise the scanner, read the token, publish under a name that thousands of builds already fetch.
The provenance arithmetic here is small enough to check by hand. litellm's GitHub releases stop at v1.82.6.dev1 [3], and 1.82.7 and 1.82.8 were pushed straight to PyPI without passing through the project's CI [4]. The two poisoned artifacts are therefore exactly the versions with no CI-built counterpart [1], which is also why the proxy Docker image came through clean: litellm says those dependencies are pinned in requirements.txt [10].
The issue names the hijacked account as krrishdholakia and the attacker's as teampcp [9]. Maintainer accounts have been rotated to @krrish-berri-2 and @ishaan-berri, and litellm says no further releases ship until it has scanned its chain [18]. Google's Mandiant is engaged [14].
Scoping is where this gets expensive. The stolen material was encrypted with AES-256-CBC under a hardcoded RSA-4096 public key before the curl POST to models.litellm.cloud [6]. A captured payload tells a responder nothing about its contents, so the loss cannot be narrowed from the outside, and the defensible assumption is the full collection list [2]. litellm's own guidance matches that: rotate every credential present as an environment variable or config file on any system where 1.82.7 or later was installed [17]. The on-disk marker is litellm_init.pth in site-packages [16].
PyPI suspended the project outright rather than yanking two files, and every version now returns "No matching distribution found" [8]. The maintainers' status header says the compromise is contained and current releases are free of the compromised component [11], while the removal means there is currently nothing to install from PyPI at all [3]. Correct trade, and an outage for anyone whose build resolves litellm at install time.
One operational detail worth carrying: the original technical writeup, issue #24512, is closed under what the maintainers describe as hundreds of spam comments from the attacker, who they say is suppressing discussion, and they redirected readers to the Hacker News thread [15]. Burying the analysis thread costs the attacker nothing and it works on everyone who arrives late.
Ranked by verification strength, evidence, and original report placement.
PyPI has suspended or removed the entire litellm package; all versions currently return "No matching distribution found". The malware was reported to PyPI via the official "Report malware" form.
The issue summary says the maintainer's PyPI account (krrishdholakia) appears to have been hijacked by an attacker using the account teampcp, who published malicious versions that steal credentials and exfiltrate them to an attacker-controlled server.
Versions 1.82.7 and 1.82.8 on PyPI were uploaded directly by the attacker and were never released through the official GitHub CI/CD.
The malicious code collects SSH keys, environment variables including API keys and secrets, AWS/GCP/Azure/Kubernetes credentials, crypto wallets, database passwords, SSL private keys, shell history and CI/CD configs.
The collected data is encrypted with AES-256-CBC plus RSA-4096 using a hardcoded public key, then exfiltrated by curl POST to https://models.litellm.cloud/.
Distinct publishers with included, body-backed reporting in this cluster.
Follow any of these and your For You feed starts watching them — no settings page required.
security
The 2,500-org compromise was a Trivy problem. LiteLLM was the closing act.1 distinct publisher
science
TeamPCP hid its infostealer inside the scanners that audit everyone else's code1 distinct publisher
science
LiteLLM 1.82.7 and 1.82.8 shipped an infostealer: rotate everything those machines touched1 distinct publisher
security
AFP charges two men near Perth over the self-spreading worm behind the TeamPCP compromises1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
One first-party thread, unusually specific
For a supply-chain story the technical grain is good: a filename and SHA256, an exact exfiltration URL, a named registrar, a version boundary against GitHub releases. But it all arrives from a single incident thread posted by the compromised project, and the one document that would corroborate it — the original analysis in issue #24512 — is closed under the attacker's spam. PyPI's removal, the account takeover and the Trivy attribution are each stated once, by the party with the most at stake.
No exposure numbers anywhere
We can see what happened to the package — two poisoned uploads, then the whole project pulled from PyPI — but nothing about reach. No download figures for the window, no count of hosts that found litellm_init.pth, no affected organisations, not even a start time for when 1.82.7 went live. Scale is the question this reporting cannot answer.
Containment claimed ahead of the work
The malware description is sober and unembellished — itemised, hashed, no adjectives. The overstatement sits in the reassurance: a header announcing containment and clean current releases, above a thread that admits other versions may be affected, no releases are being published, every version is gone from PyPI, and the blast radius is still being scanned. That gap points at comfort, not at drama.
The breached vendor writes the only record
Two interested parties shape what a reader can see. litellm has reason to locate the failure in a third-party scanner, to lead with containment, and to bound the impact around its own Docker image — while also, to its credit, telling users to rotate everything. The attacker has reason to bury the independent technical analysis, and by the maintainers' account has done exactly that with hundreds of comments. Nobody in this story is a disinterested observer.
Credible in substance, shaky in bookkeeping
The direction of the story looks solid — a hijacked publisher account, unsigned artefacts above the CI line, a lookalike exfiltration host. What weakens it is the record-keeping around those facts: attribution is hedged as something that 'appears' to have happened, the WHOIS date given for the exfiltration domain sits months rather than hours before this thread, and other affected versions are gestured at rather than listed. Enough to act on, not enough to consider settled.