Analysis
The lightning Python package on PyPI — a widely-used distributed training framework in the Python machine learning ecosystem — was compromised on April 30, 2026. Malicious versions 2.6.2 and 2.6.3 were identified and removed from the registry. A group calling itself Team PCP claimed responsibility via a Tor onion site linked from a GitHub issue on the project.
Lightning receives several hundred thousand downloads per day from Python ML environments, making this the highest-volume PyPI target in the TeamPCP cluster documented to date. The attack follows the TeamPCP pattern established in litellm (March 24) and elementary-data (April 30): compromise a CI/CD pipeline or package account to publish malicious versions, execute on import, harvest credentials using a Bun-runtime loader, and exfiltrate. The distinguishing feature in this campaign is the exfiltration channel: rather than posting to a dedicated C2 domain, the malware commits AES-encoded stolen data to attacker-controlled GitHub repositories. This makes the exfiltration traffic indistinguishable from legitimate GitHub API calls — standard network egress monitoring cannot block it without blocking GitHub entirely.
The Bun runtime loader pattern and tooling overlap with Shai-Hulud and Mini Shai-Hulud were noted by Socket in their primary analysis. Primary-source verification of the specific Bun version pin is pending (Task #15); if confirmed as v1.3.13, this becomes a high-confidence linking artifact with the existing cluster.
What we know
- April 30, 2026 — Socket published primary analysis of the compromise. Malicious versions 2.6.2 and 2.6.3 identified and removed from PyPI.
- Clean version: 2.6.1, published January 30, 2026, is reported clean by Socket.
- Self-attribution: TeamPCP claimed responsibility via a Tor onion site linked from a GitHub issue on the lightning project repository. This is Layer 1 self-attribution — the operator named themselves at the point of disclosure.
- Download volume: Several hundred thousand downloads per day from Python ML environments. Lightning is used across AI/ML training pipelines, academic computing clusters, and production ML infrastructure.
Why lightning was targeted
The lightning attack surface profile is the broadest in the TeamPCP PyPI branch. Lightning is not a narrow LLM proxy (litellm) or a distributed analytics tool (elementary-data) — it is a foundational distributed ML training framework used across the full spectrum of Python ML development:
- Cloud training credentials at maximum scope. Lightning deployments run on AWS, GCP, and Azure compute with credentials scoped for GPU cluster management, storage access, and model registry write. These credentials have broader scope than typical production service credentials.
- Research and production in the same codebase. Lightning spans academic research environments (where security controls are weaker) and production ML infrastructure (where the credential blast radius is highest). A single compromised PyPI installation reaches both.
- CI/CD integration for automated training runs. Automated retraining pipelines running on CI/CD hold the combination of cloud credentials and PyPI publish tokens that the TeamPCP worm exploits for propagation. Lightning's prevalence in automated ML pipelines puts it squarely in the propagation surface TeamPCP has been systematically targeting.
- Scale as the selection criterion. Socket reports hundreds of thousands of downloads per day. At that scale, even a brief window of malicious versions in the registry produces thousands of compromised environments before the package is yanked.
Payload mechanics
The following analysis is from Socket's primary report, as characterized by Datadog Security Research. Primary-source payload artifact verification is pending (Task #15).
The malicious code is bootstrapped by a start.py module that runs when the package is imported — not at install time. This is a different trigger point than the litellm .pth file (which executed at Python startup) and the elementary-data postinstall hook (which executed during npm install). An import-triggered payload means it does not execute in environments that install the package but never import it — a narrower trigger than .pth injection but still broad given lightning's usage patterns.
The bootstrapper detects host OS and architecture, downloads the Bun JavaScript runtime from GitHub, and launches a hidden _runtime/router_runtime.js payload as a daemon thread with suppressed output. The Bun runtime is downloaded from GitHub at runtime rather than bundled in the package — this keeps the malicious package size normal and means static package analysis tools scanning the tarball for suspicious content will not find the payload directly.
The second stage is an 11 MB obfuscated JavaScript bundle. Socket describes hundreds of references to environment variables and authentication tokens within the payload. Collection targets include:
- GitHub personal access tokens and GitHub Actions tokens
- npm publish tokens from
.npmrc - Cloud provider credentials from environment variables and on-disk configuration files
- Other secrets accessible from the developer or CI environment
Socket reports two uses of stolen tokens after collection. First, the malware commits AES-encoded exfiltrated data to attacker-controlled repositories. Second, it tampers with downstream npm package tarballs in repositories to which the victim holds push access — the propagation mechanism.
The GitHub dead-drop exfil channel is the operational innovation in this campaign. Exfiltrating data via commits to attacker-controlled GitHub repositories means the outbound traffic is GitHub API calls — HTTPS to api.github.com. Any organization that has not implemented content-level egress inspection cannot distinguish this from a developer pushing code. The standard detection action for supply-chain C2 (block the C2 domain) does not apply. Detection must occur either at the package install/import stage or via behavioral analysis of GitHub API call patterns from unexpected processes.
Cluster position and Bun linking artifact
Lightning is the fourth confirmed PyPI victim in the TeamPCP cluster, following litellm (March 24), Xinference (April 22), and elementary-data (April 30). The Bun-runtime loader pattern is consistent across all PyPI victims — TeamPCP standardized on Bun after establishing the technique in the npm cluster (Shai-Hulud, Mini Shai-Hulud).
Socket notes tooling overlap with Shai-Hulud and Mini Shai-Hulud. In the existing cluster analysis, the Bun v1.3.13 pin is a high-confidence linking artifact: pinning to a specific non-LTS Bun point release is a deliberate build choice that independent codebases would not make identically. If Socket's primary analysis confirms v1.3.13 in the lightning payload, this is the same proof of shared codebase that links Shai-Hulud and Mini Shai-Hulud. That verification is the open task (Task #15).
Indicators of compromise
Compromised versions:
lightning==2.6.2— malicious; payload in bootstrapper loaded at importlightning==2.6.3— malicious; same payload chainlightning==2.6.1— clean (reported by Socket)
Filesystem artifacts:
_runtime/router_runtime.jswithin the lightning package directory — 11 MB obfuscated bundle; presence of this file in site-packages confirms malicious version was installed- Bun binary downloaded to a temporary or hidden path at import time — anomalous binary appearing in temp directories during Python process execution
Network indicators:
- Outbound connections to GitHub API for commit operations from within a Python process during model training or package import — not normal behavior
- Bun runtime download from GitHub during Python package import — a Python ML package has no legitimate reason to download the Bun JavaScript runtime
Campaign self-attribution (Layer 1):
- Tor onion site linked from lightning GitHub issue — TeamPCP claiming responsibility at disclosure
Detection and mitigation
- Upgrade immediately. Any environment with
lightning==2.6.2or2.6.3installed should be treated as compromised. Pin to a version after 2.6.3 once Socket and the lightning maintainers confirm a clean release. - Audit for
_runtime/router_runtime.js. Runfind $(python3 -c "import site; print(' '.join(site.getsitepackages()))") -name "router_runtime.js" 2>/dev/null. Presence confirms malicious version was installed and the payload loaded. - Rotate all credentials from affected environments. The collection scope includes GitHub tokens, npm tokens, and cloud credentials. Any environment that imported the malicious version should be treated as fully compromised — all accessible secrets rotated.
- Check for worm propagation via npm publish tokens. If the environment held npm publish tokens, check for unexpected patch releases on any packages those tokens could access. TeamPCP uses stolen publish credentials to extend the worm downstream.
- Audit GitHub API call patterns from ML pipeline processes. Commit operations originating from a Python ML training process are not expected behavior. If your SIEM ingests GitHub audit logs, alert on commits from CI systems running lightning during the April 30 window.
- Detect Bun download in Python contexts. Any process with a Python parent downloading Bun binary artifacts from GitHub is anomalous. This behavioral rule covers the TeamPCP Bun-runtime loader pattern across all PyPI victims, not just lightning.
Attribution and cluster position
TeamPCP's self-attribution via Tor-linked GitHub issue on April 30 is consistent with the campaign's pattern of claiming victims at disclosure. The claimed LAPSUS$ connection noted in Socket's analysis remains unverified and is not assessed to change the threat model for defenders.
See the npm supply-chain worm cluster analysis for the full cluster timeline and the technical analysis connecting TeamPCP, Shai-Hulud, Mini Shai-Hulud, and CanisterWorm through the Bun version pin and __decodeScrambled build artifact.
Criminal-market signal
TeamPCP sweeps across multiple runs have returned clean negatives. The operator-run credential-collection model documented across the cluster applies to lightning. The GitHub dead-drop exfil is consistent with the operator using credentials directly rather than selling access — a broker or commodity actor would use a simpler, more operationally detached exfil channel. No dark-web presence for lightning compromise tooling is expected or has been observed (H2 operator-run pattern).