AI Security

LiteLLM: 1 Malicious Release Pushed via Harvested GitHub CLI Tokens

LiteLLM's release pipeline was compromised on October 21, 2026, pushing a malicious v1.107.0 with a credential stealer and backdoor to PyPI, Docker Hub, and GHCR. The maintainers suspect the attacker harvested GitHub CLI OAuth tokens from logs of an internet-exposed internal deployment.

Y
Yso Series
October 22, 2026 · 4 min read · 0
litellmsupply-chainpypigithubcredential-theftllmjackingincident-response

On October 21, 2026, at approximately 4:00 a.m. PST, the release pipeline of LiteLLM, BerriAI's open-source LLM gateway and proxy, was compromised and a malicious version, litellm v1.107.0, was published to PyPI, Docker Hub, and GHCR carrying a credential stealer and a remote-access backdoor. According to LiteLLM's incident advisory, the maintainers suspect the attacker harvested GitHub CLI OAuth tokens from logs of an internal LiteLLM deployment that was exposed to the public internet, then used those credentials to force poisoned artifacts through the project's own signing and release workflow. The package was live on PyPI for roughly two hours before it was pulled.

What was the specific vulnerability?

The specific vulnerability was a supply-chain compromise: malicious code was signed and distributed through LiteLLM's legitimate release channels after the attacker obtained three sets of developer GitHub CLI credentials, including one belonging to a GitHub organization owner.

The poisoned package shipped a .pth file named "cook.pth" that imports "cook.py," which runs a stealer routine called "privcollect" to gather system, browser, developer, cloud, and AI tool secrets and exfiltrate them via HTTP POST to "litellm[.]dev/healthcheck." A second mechanism, "sitecustomize.py" on Linux and macOS, fetches a file called "domain.txt" from a GitHub dead drop at the account "letters9813" and then downloads and executes a second-stage Python payload from "{domain}/codepy" on an hourly cycle, holding a lock file at /tmp/remote_code_loader.lock.

The attack chain began on October 19, when LiteLLM temporarily expanded release permissions for two internal engineers to publish daily bugfix backports. The attacker used the harvested GitHub CLI credentials, including a token able to run GitHub workflows, to disable branch protections and force-push malicious changes, then ran the compromised workflow pointed at a lookalike repository, "Berri-AI/litellm" rather than "BerriAI/litellm," causing the poisoned artifacts to be signed and published. As for the root cause, LiteLLM states that "Claude Code will embed a user's GitHub CLI OAuth token into a response body, and in situations where response bodies are logged, these tokens may appear in LiteLLM logs." The maintainers found an "unexpected, innocuously named user account" in the exposed internal deployment and suspect the attacker accessed it, harvested the tokens from its logs, and used them against the release workflow. How the deployment became publicly reachable is unclear; LiteLLM theorizes it was likely through a recently patched vulnerability.

How was the incident detected?

The incident was detected on October 21, 2026, by LidorMachluf, who is credited by LiteLLM with helping detect the compromise and reporting it to the maintainers the same day.

Subsequent analysis came from Aikido researcher Ilyas Makari, who examined the remote-access behavior, and from Wiz researchers Benjamin Read and Rami McCarthy, who tracked the post-exploitation credential abuse. According to Wiz, the attacker validated AWS instance role credentials captured from compromised CI runners and Kubernetes nodes between 4:20 p.m. and 5:01 p.m. UTC on October 21, roughly 4.5 hours after exfiltration, from the IP addresses 168.100.8[.]57 and 165.227.201[.]8. Each credential was checked with sts:GetCallerIdentity, followed by bedrock:ListFoundationModels and a ListModels call, which Wiz described as "consistent with LLMjacking." In some environments the attacker also enumerated IAM with ListRoles, ListUsers, and ListAccessKeys, and performed general discovery with ListAccounts and DescribeTrails. Read and McCarthy said the dual-technique approach, using both .pth files and sitecustomize.py simultaneously, "appears to be the first documented case in the wild." The GitHub dead-drop domain.txt file had only been populated with initial test values before GitHub took it down around 1:30 p.m. UTC.

What is the current impact?

The current impact is limited to users who installed or pulled the compromised v1.107.0 artifacts during the exposure windows on October 21; enterprise customers on LiteLLM's private registry were not affected.

The PyPI package litellm==1.107.0, all seven of its wheels, was live from 11:39:51 to 13:23 UTC. Docker Hub images tagged v1.107.0, latest, main-latest, and main-stable pointed to the compromised image digest sha256:1bbcb1443bc9… from 11:46:56 to 14:20 UTC, and GHCR images were made unavailable by 13:51 UTC. Per LiteLLM's advisory, anyone who installed an unpinned version during those windows, or ran the affected Docker tags, is treated as potentially exposed to the stealer and backdoor, and the remediation guidance assumes those users' credentials may have been collected. What was at stake includes system, browser, developer, cloud, and AI tool secrets, AWS instance role credentials from CI runners and Kubernetes nodes, and provider keys stored in LiteLLM proxy databases. All compromised artifacts have since been pulled from PyPI, Docker Hub, and GHCR, and LiteLLM's advisory, last updated 20:30 UTC on October 21, lists the incident status as "Incident contained, investigation in progress."

What are the next steps?

The next steps, per LiteLLM's advisory, are to pin to version 1.106.2 or any explicit prior version, purge the malware files, and rotate every credential the affected host could reach.

Specifically, LiteLLM instructs users to delete cook.pth, cook.py, sitecustomize.py, and matching .pyc files from site-packages, kill the detached daemon, rebuild images and virtual environments, and rotate the instance or task IAM role, every provider key in the LiteLLM proxy database including master and virtual keys, the DATABASE_URL password, and any host-environment secrets. Users are also told to check CloudTrail for GetCallerIdentity calls from the instance role around the time of installation. On attribution, The Hacker News reports that LiteLLM had hardened its pipeline after a similar March 2026 compromise attributed to TeamPCP, moving releases to a private repo, adopting immutable Docker tags, and signing images. Socket told The Hacker News there is no evidence linking the two incidents: "The embedded RSA public keys differ, as do the exfiltration implementation and backdoor behavior."

By the numbers

Source snapshot

Source snapshot
Source snapshot
Share this article