PyPI Supply Chain Attacks: The LiteLLM and Telnyx Cases with Practical Recommendations
Attackers compromised the litellm and telnyx packages by leaking an API token from the Trivy dependency. On March 19, 2026, malicious versions were published: litellm 1.82.7 and 1.82.8, telnyx 4.87.0 and 4.87.2. The code activates upon importing the modules, scans the environment for secrets, and exfiltrates data to remote servers.
The malicious payload in litellm collects SSH keys, Git/Docker credentials, .env files, K8s tokens, database passwords, LDAP configs, shell history, and crypto keys. It attempts to extract cloud tokens from metadata servers and AWS Secrets Manager. Data is sent to models.litellm.cloud. For persistence, it creates a SystemD service named "System Telemetry Service" or a K8s pod that loads instructions from checkmarx.zone.
In telnyx, the malicious code in _client.py loads stages from WAV files hosted at 8.42.209.203. On Windows, it places msbuild.exe in the Startup folder for auto-launch; on other OSes, it uses a Python script. Version 4.87.1 contained a typo that blocked execution. Communication is linked to TeamPCP via an encryption key.
Developers responded by rotating tokens, removing releases, and implementing trusted publishers on PyPI.
Characteristics of Attacks on Popular OSS Packages
Unlike typical PyPI attacks (like typosquatting or new packages), here malicious code was injected into existing high-traffic projects. The chain: compromising repositories → stealing PyPI/GitHub tokens → publishing malware → collecting credentials from dev machines → repeated compromises.
LiteLLM was downloaded over 119k times during the attack. ~40-50% of installations were without version specification (latest), ~1700 installations/minute. PyPI response times:
- LiteLLM: from publication to quarantine — 2 hours 32 minutes (13 user reports).
- Telnyx: 3 hours 42 minutes (auto-quarantine by trusted users).
PyPI Measures Against Malware
Approximately 700-800 new projects are added daily. PyPI relies on the community for scanning and reporting via "Report as malicious." This feature, introduced in 2024, speeds up quarantine. Trusted publishers enable automated responses.
Recommendations: Dependency Cooling-Off Period
Delaying installation of new releases provides time for malware detection. Format: RFC 3339 (P3D = 3 days).
- uv: globally in ~/.config/uv/uv.toml or pyproject.toml:
[tool.uv]
exclude-newer = "P3D"
- pip v26.1+: in pip.conf:
[install]
uploaded-prior-to = P3D
- pip 26.0 (absolute date):
python -m pip install --uploaded-prior-to=$(date -d '-3days' -Idate) package
Workaround for security patches: --uploaded-prior-to=P0D or Dependabot/Renovate (which ignore delays).
Locking Dependencies for Reproducibility
Lock files with hashes prevent code substitution during reinstall.
| Tool | Command | Format |
|------------|---------|--------|
| uv | uv lock | uv.lock |
| pip-tools | pip-compile --generate-hashes | requirements.txt |
| pipenv | pipenv lock | Pipfile.lock |
pip freeze is insufficient — lacks hashes. pip lock (pylock.toml) is expected.
Protecting OSS Projects
- Implement trusted publishers on PyPI.
- Use 2FA + hardware keys for PyPI/GitHub.
- Restrict token permissions (scopes).
- Monitor publications via webhooks.
- Scan repositories with Trivy/Grype.
For dev machines:
- Isolate compromised environments.
- Rotate all credentials.
- Check for persistence (SystemD, K8s pods, Startup).
- Analyze traffic/logs.
Key Takeaways
- Attacks exploit real OSS packages; verify new releases.
- A P3D cooling-off period + lock files = basic protection.
- Over 119k LiteLLM installations before quarantine; latest is risky.
- Exfiltration includes cloud metadata and Secrets Manager.
- Trusted publishers and community speed up PyPI response.
— Editorial Team
No comments yet.