PyTorch Lightning Compromised: Your ML Supply Chain Just Failed the Way Software's Did Five Years Ago
What Happened
On April 30, attackers hijacked PyPI publishing credentials for PyTorch Lightning and pushed tampered builds of versions 2.6.2 and 2.6.3 during a 42-minute window. The payload fires on import, so no training job needs to run. It spawns a background thread, installs Bun, executes an obfuscated JavaScript payload, and exfiltrates cloud credentials, browser-stored secrets, .env files, and GitHub tokens. The Python-to-Bun/JS handoff is built specifically to evade Python-only static analysis.
Why 42 Minutes Is Worse Than It Sounds
Count the scheduled CI jobs, nightly retrains, and notebook kernels that fire pip install inside any 42-minute window at a mid-sized ML shop. The answer is more than you want to explain in the incident review. Import-time execution means a single pip install lightning on a CI runner was enough for full credential exposure. No training, no notebook execution required.
The blast radius is not the training cluster. It's the researcher laptops with long-lived cloud credentials, the shared notebook environments with read access to feature stores, and the CI runners that build model images with secrets mounted.
The Broader Pattern
This is the same class of supply-chain failure that hit general software five years ago, and most ML teams are responding with first-generation tools. Dependency pinning helps. SBOMs help. Neither would have caught this at install time, because the signal you needed was "this specific point release started behaving unlike its siblings." That is a runtime and provenance question, not a manifest question.
Separately, a new marketplace called Asset Hub is now selling defunct-startup Slack archives, Jira tickets, and email threads as premium LLM training data. Operational exhaust with no individual consent trail. Training-data provenance is now a governance problem, not a compliance checkbox.
Immediate Actions
- Grep for
lightning==2.6.2and2.6.3across lockfiles,requirements.txt,poetry.lock, Dockerfile base images, and CI caches. Pin to 2.6.1. - Rotate all cloud IAM keys, GitHub PATs, and browser-stored secrets reachable from any machine that may have pulled those versions. Review 30 days of egress logs for anomalous outbound traffic.
- Enforce hash-pinned dependencies (
pip-toolsoruvwith--require-hashes) in all production ML images this sprint. On the evidence available, this is the single highest-ROI MLSecOps control. - Add egress monitoring to training clusters and CI runners. The assumption that package managers are trustworthy is empirically wrong.
Treat MLSecOps as a separate discipline from DevSecOps. Research environments are permissive by design, dependencies churn faster, and the people running the code optimize for iteration speed rather than signed artifacts. If research and production share the same identity plane, you inherit the worst of both.
What to do
Grep all lockfiles, Dockerfiles, and CI caches for lightning==2.6.2 or 2.6.3; pin to 2.6.1
Rotate all cloud IAM keys, GitHub PATs, and browser secrets on machines that may have been exposed
Enforce hash-pinned dependencies via pip-tools or uv --require-hashes in all ML Docker images by end of sprint
Require data-source disclosure with named upstream providers from any training-data vendor; flag Asset Hub-sourced corpora