How a non-expert with Claude Code caught the LiteLLM supply chain attack in real time
Callum McMahon was doing his job. On the morning of March 24, his Cursor IDE pulled in a Python library called litellm as a dependency, and something went wrong — his laptop froze, 11,000 Python processes filling the screen. He assumed it was a runaway agent loop. He was not wrong about the loop, but wrong about the cause. The library itself was poisoned, published to PyPI thirteen minutes earlier by an attacker who had stolen the project's publishing credentials. McMahon, a research scientist at FutureSearch with no formal malware training, had become patient zero for a supply chain attack on one of the most widely downloaded Python packages in the world.
He turned to Claude Code to figure out what happened. What followed is documented in a live transcript McMahon published on futuresearch.ai — Simon Willison later shared it on his blog. The record shows a minute-by-minute account of a non-expert using an AI coding assistant to find, analyze, and report a supply chain attack in real time. PyPI quarantined the malicious package roughly 100 minutes after McMahon's first message to security@pypi.org.
LiteLLM, for context, is an open-source Python library that lets developers talk to multiple LLM providers through a single API. According to BleepingComputer, it sees over 3.4 million downloads per day and 95 million in a typical month. The version that landed on McMahon's machine was 1.82.8, published to PyPI at 10:52 UTC on March 24 — six minutes before his Cursor pulled it. A second malicious version, 1.82.7, had gone up at 10:39 UTC. PyPI quarantined the malicious versions at 13:38 UTC, and the compromised versions were deleted and the package unquarantined at 15:27 UTC.
The attacker was TeamPCP — the same group behind the Trivy compromise in March and the Checkmarx KICS breach. Researchers at Snyk confirmed the link: all three operations share an identical RSA-4096 public key embedded in the payload. The group, also known as PCPcat, Persy_PCP, ShellForce, and DeadCatx3, has been active since at least December 2025, according to Snyk's analysis. In the LiteLLM attack, they went further than the earlier campaigns. The new trick was a file called litellm_init.pth placed in site-packages. Python executes .pth files automatically on every interpreter startup, not just when the package is imported — meaning the malicious code ran every time McMahon opened a terminal, with no explicit invocation required.
The .pth file contained a base64-encoded payload that, once decoded, deployed a credential harvester. According to Endor Labs and Snyk's analysis, it collected SSH keys, AWS and GCP cloud tokens, Kubernetes service account tokens, .env files, database passwords, crypto wallets, and shell history. Data was encrypted with RSA and sent to models.litellm.cloud — a domain registered March 23, one day before the attack, and not to be confused with the legitimate litellm.ai. The payload also installed a persistence script at ~/.config/sysmon/sysmon.py with a systemd service, and attempted to spread laterally through Kubernetes clusters by deploying privileged alpine:latest pods to every node.
McMahon's transcript is where the story earns its headline. After confirming the malicious file in a Docker container — a step Claude Code helped him execute safely — he asked whether he should report it. The response: "This needs to be reported to security@pypi.org immediately." He did. He also emailed LiteLLM's maintainers directly and opened a GitHub security advisory. Total elapsed time from first suspicion to filed report: under an hour. The compromised LiteLLM maintainer account then closed his GitHub issue with bot comments — he noted the irony in the transcript with a dry aside.
BleepingComputer, citing sources and VX-Underground, reports approximately 500,000 data exfiltrations, though that figure could not be independently confirmed as of publication. LiteLLM has since engaged Mandiant for forensic analysis, rotated all maintainer credentials, and established new authorized publishers, according to the company's security update.
The standard framing for this story is "AI helps find malware." That is true but insufficient. The more interesting observation is that McMahon, without security expertise, moved faster than automated tooling. No scanner flagged it. His own machine, brought to its knees by the attack's fork bomb behavior, was the detection system. The malware's persistence mechanism — spawning a subprocess on every Python startup, which triggered the .pth again, which spawned another subprocess — created the very symptom that made the infection impossible to ignore. The attack's persistence was its tell.
What the transcript documents is not a clever AI trick. It is the speed at which an AI-assisted non-expert can close the gap between suspicion and confirmation when something genuinely novel lands on their machine. The malware was live on PyPI for roughly 100 minutes before someone with no security background identified it, verified it in isolation, and filed a report. Automated systems, running continuously on millions of machines, missed it entirely. The delta between human + AI and automated detection, in this case, was not in the tooling's favor.
Whether that delta holds in the general case is an open question. But in the LiteLLM case, the human won.