What Happened
On March 24, 2026, threat actor TeamPCP released two compromised versions of the Python package litellm—versions 1.82.7 and 1.82.8. These contained a multi-stage attack toolkit, including a credential harvester, a Kubernetes lateral movement toolkit, and a persistent backdoor. The attack vector was not a developer's laptop or a weak password—it was Trivy, the open-source vulnerability scanner many teams use in their CI/CD pipelines.
TeamPCP compromised the CI/CD workflow itself, turning a tool designed to catch security issues into a means of injecting them. Organizations running automated security scans inadvertently pulled and deployed compromised packages that exfiltrated credentials and established persistence mechanisms across their infrastructure.
Timeline
March 24, 2026: Litellm versions 1.82.7 and 1.82.8 were published to PyPI containing malicious payloads.
Initial compromise phase: Malicious code executed during package installation, establishing a systemd service that polls checkmarx[.]zone/raw every 50 minutes for new payloads.
Exfiltration phase: Credential harvester begins sending data to models.litellm[.]cloud via HTTPS POST requests.
Detection: Security researchers identified the compromise after observing anomalous network behavior and analyzing the package contents.
Which Controls Failed or Were Missing
The attack succeeded because multiple defensive layers either didn't exist or failed to activate:
No package integrity verification: Teams installed packages without verifying signatures or checksums against known-good versions. When litellm 1.82.7 appeared in the dependency tree, automated systems pulled it without validation.
Missing egress monitoring: The payload exfiltrated data to models.litellm[.]cloud via HTTPS POST requests, but no network controls flagged unusual outbound connections from build environments or application servers.
Inadequate CI/CD pipeline isolation: The compromised Trivy scanner ran with sufficient privileges to modify package installations. Build environments lacked the segmentation needed to contain a compromised security tool.
No runtime behavior monitoring: The systemd service polled an external domain every 50 minutes, a clear indicator of compromise. Yet no runtime security controls detected the persistence mechanism or the regular beacon pattern.
Absent dependency pinning: Applications likely specified litellm without version constraints (e.g., litellm>=1.82.0), allowing the malicious versions to be automatically pulled during dependency resolution.
What the Relevant Standards Require
This incident maps directly to multiple control failures across frameworks:
NIST 800-53 Rev 5 SI-7 (Software, Firmware, and Information Integrity) requires organizations to use integrity verification tools to detect unauthorized changes to software. This includes verifying digital signatures and checksums before installation. Your package installation process should reject any artifact that fails integrity checks.
PCI DSS v4.0.1 Requirement 6.3.2 mandates that custom software be developed in accordance with secure coding practices, including validation of input from all sources. While this requirement targets custom code, the principle extends to your supply chain: you must validate what enters your environment, whether you wrote it or pulled it from PyPI.
ISO/IEC 27001:2022 Control 8.31 (Separation of Development, Test and Production Environments) requires logical separation between environments. Your CI/CD pipeline is a production environment for your build process. A compromised security scanner should not have write access to production package repositories or the ability to modify what gets deployed.
NIST Cybersecurity Framework (CSF) v2.0 PR.DS-6 calls for integrity checking mechanisms to verify software integrity. This means your artifact pipeline needs cryptographic verification at every stage—not just for your code, but for every dependency that becomes part of your runtime.
SOC 2 Type II CC6.8 requires that entities monitor infrastructure and software for potential security vulnerabilities. The 50-minute polling interval to an external domain represents exactly the kind of anomalous behavior that should trigger alerts in a properly instrumented environment.
Lessons and Action Items for Your Team
Stop treating your CI/CD pipeline as a trusted environment. It's infrastructure that processes untrusted input—in this case, third-party packages and security tools themselves.
Pin your dependencies with hash verification: Replace litellm>=1.82.0 with exact versions and SHA256 hashes. Use tools like pip-tools or Poetry to generate lock files that specify not just versions but cryptographic hashes. When a new version appears, your build should fail until someone explicitly reviews and updates the lock file.
Implement egress filtering for build environments: Your CI/CD runners should not have unrestricted internet access. Create an allowlist of necessary domains (package repositories, artifact registries) and block everything else. The exfiltration to models.litellm[.]cloud would have failed immediately.
Isolate security scanning tools: Run Trivy and similar scanners in separate, restricted containers or VMs with read-only access to your codebase. They should report findings but lack the ability to modify packages or deployment artifacts. This maps directly to ISO/IEC 27001:2022 Control 8.31's separation requirements.
Monitor for persistence mechanisms: Deploy runtime security tools that detect new systemd services, cron jobs, or startup scripts. The 50-minute polling interval represents a clear behavioral signature. Configure alerts for any process establishing scheduled external communications.
Verify package signatures when available: Python packages can include PGP signatures. Configure your package manager to verify signatures for critical dependencies. For packages without signatures, maintain an internal mirror where you re-sign packages after manual security review.
Audit your current dependencies: Run pip list or equivalent across all environments. Check if you installed litellm 1.82.7 or 1.82.8 between March 24 and when the compromise was disclosed. If yes, assume full compromise: rotate all credentials accessible from those environments, review systemd services, and check for outbound connections to checkmarx[.]zone and models.litellm[.]cloud.
The sophistication here isn't the malware—it's the attack vector. TeamPCP didn't need to find a zero-day or phish your developers. They compromised a security tool that your CI/CD pipeline trusts implicitly. Your next security assessment should include this question: what happens if the tools that check our security get compromised?



