HomeTech NewsCybersecurityMalicious LiteLLM Release on PyPI Stole Credentials, Researchers Say

Malicious LiteLLM Release on PyPI Stole Credentials, Researchers Say

For roughly two hours on Wednesday, by SafeDep’s timeline, installing the latest version of LiteLLM from PyPI meant installing malware too.

LiteLLM is an open-source library, with more than 61,000 stars on GitHub, that in its own words lets developers call more than 100 large language model APIs in a single format. Version 1.107.0, uploaded to the Python Package Index at about 12:40 BST on 21 October, “carries a credential stealer and a remote code execution backdoor”, security firm SafeDep says. Its maintainers confirmed the compromise on the GitHub issue where it was first reported. “We are actively investigating and treating this as SEV-0. PyPI quarantined 1.107.0,” a LiteLLM contributor wrote at 14:50 BST.

PyPI has removed the release; its listing now shows 1.106.2 as the latest version. The maintainers say the malicious Docker images have also been taken down.

TSN tracks attacks like this on its ransomware and cyber attacks hub.

The malware runs even if LiteLLM is never imported

SafeDep’s analysis says all seven 1.107.0 wheels, covering Linux, macOS and Windows, drop three extra files into the Python environment, and that two of them run whenever any Python process starts on the machine, “even one that never imports litellm”. The source code on GitHub does not contain them.

The first is a credential stealer. According to SafeDep, it collects SSH keys, cloud credentials, CI/CD secrets, browser passwords and tokens for AI coding tools, and dumps the LLM provider API keys held in a LiteLLM proxy’s database. It encrypts what it finds and sends it to www.litellm[.]dev. The second file starts a background process that, every hour, reads a server address from a file on GitHub, runs the stealer again, and downloads and runs whatever code that server supplies.

SafeDep says the GitHub account hosting that address file was deleted by 14:40 BST, so the backdoor now has nowhere to call. But it warns that “hosts that ran the daemon before the deletion could have received and run second-stage code”, and it could not recover the server address.

Stolen tokens, but no confirmed entry point

How the release was made is still under investigation. In a 17:32 BST update, LiteLLM said “the malicious actions were taken through three engineers’ GitHub accounts, appearing to be by way of stolen GitHub CLI OAuth tokens”. One account triggered the project’s release job and another approved it. All the tokens involved have been revoked, and LiteLLM has removed all but one unaffected user from its GitHub organisation. It added: “We have not yet identified the original attack vector.”

SafeDep’s own reading, which it gives with moderate to high confidence, is that LiteLLM’s private release pipeline built the wheels from attacker-modified source code; it found no public GitHub Actions run that built them. “Only BerriAI’s pipeline logs can confirm the cause,” it says. The researcher who opened the issue, who signs the report as Upwind’s security research team, has suggested the release was built from a lookalike repository. LiteLLM has not confirmed that.

The maintainers say enterprise customers who pull from LiteLLM’s private registry are not affected. It resembles the attack TSN covered this week in which OVHcloud’s command-line tool was backdoored to steal secrets.

What users should do

LiteLLM’s advice to open-source users is to pin version 1.106.2 or another explicit earlier release. SafeDep says 1.106.2 and the two 1.107.0 release candidates are clean. Docker users need to check too. The reporter says any pull of the “latest”, “main-latest” or “main-stable” tags from about 12:48 BST got the infected image; the issue’s status note says those tags no longer point to it.

For machines that did install 1.107.0, the issue’s remediation steps are blunt. Running pip in the affected environment triggers the malware again, so the reporter advises deleting cook.pth, cook.py and sitecustomize.py from site-packages first, stopping the background Python process, and preferably rebuilding the environment from scratch. Any host with internet access that ran 1.107.0 should be treated as having had its secrets taken. That means rotating cloud roles, the proxy’s database password and master keys, and every provider key stored in the proxy.

Sources

Related stories

Follow @tsnmediahub on X for breaking AI news as it happens.

Follow on X

Share this story

Latest stories

More in this category

Latest stories

Explore the TSN Atlas: Every topic we cover, mapped. Click a bubble to dive in.