SANDCLOCK: LiteLLM Supply Chain Attack Siphons CI/CD Secrets

Step by step
How the attack unfolded
Click a phase for details – or let the animation play through.
PHASE 1/6 · Supply Chain Staging

The attackers set up their infrastructure and compromised the upstream scanning tool Trivy.

T1608 – Stage Capabilities T1583.001 – Acquire Infrastructure: Domains
  • 2026-03-19: Compromise of the Trivy security scanner as upstream vector
  • 2026-03-23: Registration of domains models.litellm.cloud and checkmarx.zone
  • Campaign attributed as TeamPCP / SANDCLOCK
  • Stolen CI/CD and PyPI credentials paved the way to LiteLLM
PHASE 2/6 · Initial Access via Supply Chain

Using a compromised maintainer account, two malicious LiteLLM versions were uploaded directly to PyPI.

T1195.001 – Supply Chain Compromise: Compromise Software Dependencies and Development Tools T1078 – Valid Accounts
  • 2026-03-24 10:39 UTC: version 1.82.7, 10:52 UTC: version 1.82.8 published
  • Compromised maintainer / publishing account
  • Regular hardened GitHub release channels were bypassed
  • LiteLLM is typically installed 15–20 million times per week
PHASE 3/6 · Execution

The malicious code triggered on import or even automatically at Python interpreter startup.

T1059.006 – Command and Scripting Interpreter: Python T1204.003 – User Execution: Malicious Image
  • 1.82.8 used litellm_init.pth – execution without import at Python startup
  • 1.82.7 placed the code in litellm/proxy/proxy_server.py, triggered on import
  • Particularly dangerous in CI/CD build pipelines
  • Over 119,000 downloads of the affected versions
PHASE 4/6 · Credential Collection

A credential stealer systematically harvested secrets from the environment, files and cloud services.

T1552.001 – Unsecured Credentials: Credentials In Files T1552.005 – Unsecured Credentials: Cloud Instance Metadata API T1082 – System Information Discovery
  • Captured: API keys, environment variables, SSH keys, Git/registry tokens, .env files
  • Cloud credentials for AWS, GCP and Azure
  • Kubernetes service account tokens, database and LDAP configs, shell histories
  • Analyses by OSV, Datadog and Snyk (SNYK-PYTHON-LITELLM-15762713, PYSEC-2026-2)
PHASE 5/6 · Exfiltration

The stolen data was encrypted locally and sent via HTTPS to the attacker domain.

T1041 – Exfiltration Over C2 Channel T1567 – Exfiltration Over Web Service
  • Transfer to models.litellm.cloud via HTTPS
  • Data encrypted locally before exfiltration
  • Resecurity: 152.5 GiB archive with 415,427 secret-capture files
  • Manifests for 898 GitHub owners and 2,038 repositories
PHASE 6/6 · Impact

The incident potentially exposed thousands of companies and CI/CD pipelines before PyPI quarantined the package.

  • Exposure window: LiteLLM ~40 min, PyPI 2h 32m until quarantine
  • CloudSEK: >2,500 companies, 434,000 CI/CD pipelines potentially exposed (not confirmed victims)
  • LiteLLM rotated credentials and engaged Mandiant for forensics
  • Clean release v1.83.0 from hardened CI/CD-v2 pipeline on 2026-03-30
Short & clear answers
Frequently asked questions about this incident
Am I affected by the LiteLLM attack?
Only the PyPI versions litellm 1.82.7 and 1.82.8, available on 24 March 2026 between 10:39 and roughly 13:11 UTC, were affected. You are at risk if you installed or ran LiteLLM via pip during that window—either directly or as a sub-dependency of another package. According to the vendor, users of the official LiteLLM Proxy Docker image were not impacted.
How do I check whether I installed the malicious version?
Search your dependency files (requirements.txt, poetry.lock, Dockerfiles, etc.) as well as build and deployment logs from 24 March 2026 for the strings litellm==1.82.7 and litellm==1.82.8. On an isolated file system, look in the site-packages directory for the file litellm_init.pth, which indicates version 1.82.8. Also check DNS and proxy logs for connections to models.litellm.cloud and checkmarx.zone.
What concrete steps should I take now?
Disconnect suspicious hosts, containers and CI runners from the network before analysing them, since with version 1.82.8 merely starting Python can trigger the malicious code. Update to the clean version v1.83.0 or a verified release such as v1.82.6. Document for each affected system which credentials the process could read, then rotate them all.
What data was stolen in the attack?
The malicious code was a credential stealer that specifically harvested access data: API keys, environment variables, SSH keys, Git and registry tokens, .env files, cloud credentials for AWS, GCP and Azure, Kubernetes service-account tokens as well as database and LDAP configurations. The stolen data was encrypted and sent via HTTPS to the attacker domain models.litellm.cloud.
Is updating to the new version enough to be safe?
No. An update removes the malicious code, but any credentials already exfiltrated remain in the attackers' hands. You must rotate all credentials the affected processes could read and, depending on whether personal data was involved, review your GDPR obligations. The compromised versions have already been removed from PyPI.
More security news
You might also be interested in
Critical Elementor Pro Flaw: Attackers Can Fully Take Over WordPress Sites
A file upload bug in Elementor Pro up to 4.2.1 allows RCE without login. Version 4.2.2 fixes the flaw – update now!
Pods Plugin: Critical Flaw Enables Admin Takeover, No Login
A critical flaw in the WordPress plugin Pods lets attackers overwrite admin passwords without login. Over 100,000 sites are affected.
miniOrange SAML SSO: Critical Bypass Turns Attackers Into Admins
Two critical auth bypasses in the miniOrange SAML SSO plugin allow forged SAML assertions—up to full WordPress admin access.