A Poisoned Python Package Turned a Developer Laptop Into a Credential Haul

The installer looked routine. A developer on a Windows machine ran a Python command to add an unrelated dependency, and the collector started. There was no import of the compromised library, no call to it, no sign in the terminal. Starting the interpreter was enough.

Microsoft published a reconstruction of that chain on Oct. 23, two days after the LiteLLM release 1.107.0 was pulled. The package is an open-source gateway that sits between applications and model providers, and it is downloaded roughly 22.8 million times a week. On Oct. 21, a compromised build of version 1.107.0 reached the Python Package Index and the project’s official container images, including the tags most deployments pull by default.

Seven wheels carried the payload. Two files did the work: cook.pth, which Python executes at interpreter startup through its path configuration, and sitecustomize.py, which the interpreter imports automatically when the site module loads. Neither requires the application to touch LiteLLM. Any Python process in an affected environment, a test runner, a notebook, a build agent, a cron job, ran the collector.

The payload called itself privcollect. According to Microsoft’s analysis, it gathered browser data, SSH keys, GPG keys, cloud credentials, environment variables, CI secrets and configuration from more than twenty AI coding tools, encrypted the haul and sent it to an attacker-controlled endpoint. A separate module went after the LiteLLM proxy’s own database, where model-provider keys and connection strings sit. On Unix systems a second hook could pull further Python from a remote server and execute it, and a resident process was configured to fetch fresh instructions from GitHub once an hour.

The entry point was the release pipeline, not a clever exploit. LiteLLM’s maintainers said stolen GitHub credentials were used to rewrite the publishing workflow so it pushed to a lookalike repository, Berri-AI instead of BerriAI, and a credential tied to a second developer account was used to clear a production approval step. Microsoft said it had not independently established how the attacker obtained those credentials in the first place.

PyPI removed the release the same day. The container tags were repointed. That is the easy part. Microsoft’s guidance is blunt about what comes next: deleting the package does not clean the machine. The collector copies what it finds, so every credential the affected process could read should be treated as stolen, which means rotating cloud keys, model-provider keys, SSH keys, CI tokens and browser sessions, then rebuilding the environment from a known state rather than repairing it.

Detection is the other half of the response, and it is narrower than the exposure. Microsoft shipped Defender signatures and hunting queries built around the behaviour it observed on Windows and macOS endpoints: the collector’s discovery sweep, its local encryption step and its outbound connection to the staging endpoint. Investigators working from the blog are told to look in package metadata for the two startup files and to check process ancestry for interpreter launches that no user asked for.

That guidance arrives with an uncomfortable caveat. Asking whether a machine is infected by running Python or pip inside the suspect environment is exactly the action that fires the payload, so the check has to happen from outside the environment, on the filesystem and in endpoint telemetry. Two days passed between the release and the analysis. Anyone who installed on Oct. 21 and rebuilt nothing has had that window to be read.

The incident fits a pattern that security teams have watched for three years. Attackers have moved from breaking software to breaking the people who ship it, because a publisher’s pipeline is a single point that reaches thousands of downstream users at once. The xz backdoor, the tj-actions tag rewrite, the Ultralytics compromise and a long run of stolen PyPI tokens all followed the same route: a maintainer’s credential, then a release that looks legitimate because it is signed by the project itself.

What makes this one worth studying is the persistence mechanism. Most supply-chain advice assumes the damage happens when code is imported, which is why reviewers read diffs and scan dependencies. A .pth file executes before any of that logic runs, and sitecustomize.py executes for every interpreter on the box. The infection lives in the environment rather than the application, so it travels with the image, the laptop and the CI runner, and it survives a rollback of the dependency that brought it in.

The AI angle widens the blast radius. A gateway like LiteLLM holds the API keys for every model provider an organisation uses, plus the routing rules that decide which traffic goes where. A copy of that configuration is a map of how a company uses AI, and the keys are billable. Microsoft said the stolen set included developer tooling and AI application configuration specifically, which is a fair description of where value has migrated.

The practical lesson for teams running any AI gateway is unglamorous. Pin versions by hash, not by tag. Keep the gateway in its own environment so a startup hook cannot reach a developer’s browser profile. Treat any Python process that shares an environment with a third-party package as inside the blast radius. And when a compromise is announced, read the recovery guidance before the remediation: the instinct to uninstall and move on is the mistake the attackers counted on.

Related Posts

  • October 26, 2026
  • 6 views
Musk’s ‘Odyssey’ Arrives as Seven Minutes, Not a Movie

Christopher Nolan’s “The Odyssey” opened in July and kept selling out Imax screens for months. It was shot across six countries with a cast and crew in the thousands, and…

  • October 26, 2026
  • 6 views
Palantir Wrote the Rules It Then Bid Under at Britain’s Defence Ministry

In February, Louis Mosley, who runs Palantir’s British business, walked into the office of Luke Pollard, the defence procurement minister, carrying a 23-page document. It was a review of how…