Yesterday afternoon, Semgrep’s research team disclosed that versions 2.6.2 and 2.6.3 of lightning — the PyPI distribution of PyTorch Lightning, the standard high-level training wrapper used by tens of thousands of ML projects — were trojaned. Anyone who ran pip install lightning or upgraded between the release window and the takedown got a malicious payload that exfiltrated cloud credentials, persisted hooks into Claude Code and VS Code, and worm-propagated by republishing other packages from any compromised npm/PyPI tokens it could find. It’s the AI training ecosystem’s first big Shai-Hulud-style attack, and it lands squarely on the dependency every PyTorch shop has somewhere in its tree.
The Semgrep writeup is technical and worth reading, but the operational lesson is simpler: the model of “the popular packages are too well-watched to be hijacked” is over for AI/ML libraries the same way it ended for npm in 2024. If you build on top of PyTorch Lightning — or anything that depends on it transitively — you have a small window of work to do this week.
What the malware actually does
- Credential exfiltration. On import, it scans for AWS / Azure / GCP credentials, GitHub tokens, environment variables, and dotfiles in the standard locations. Anything found gets POSTed to a C2, AND copied into commit messages of public repos as “dead drops” (so the attacker can keep operating even when one channel is taken down).
- Editor persistence. The payload writes hooks into
.claude/and.vscode/in the infected repository. Every time a developer opens Claude Code or VS Code in that workspace, the hook runs — meaning the malware keeps re-stealing credentials long after the initial install. - Worm propagation. If npm or PyPI publish-tokens are present in the credentials it harvested, it injects a setup-time dropper into every package that token can publish to, and pushes new versions. Each victim that has an active publish key becomes a launch pad for the next wave.
- GitHub Actions hijack. It plants a malicious workflow that dumps the repo’s secrets to the attacker on the next CI run. So even “I noticed and uninstalled the package” doesn’t end the compromise — the workflow keeps running.
The naming convention — EveryBoiWeBuildIsAWormyBoi in the function names, Dune-themed strings sprinkled in — matches the “Mini Shai-Hulud” campaign that hit npm last year. Same operator, or someone studying their playbook.
Who’s exposed
- Anyone who installed or upgraded to
lightning==2.6.2or2.6.3between roughly mid-day Apr 30 UTC and the package’s takedown by PyPI early on May 1. - Anyone who ran an unpinned
pip install lightningin CI or in a fresh dev container during that window. - Transitively, anything that pulled
lightningas a dependency — which includes many notebook templates, the official Lightning AI Studio images, and a long tail of fine-tuning libraries.
If you’re a PyTorch user who pins versions and only updates deliberately, you may be fine. If you’re a researcher who runs pip install -U lightning in a notebook, you’re probably affected.
What to do this week
- Audit your environments. Run
pip show lightningin every Python venv / conda env / dev container you’ve touched in the last week. If it shows 2.6.2 or 2.6.3, treat that machine as compromised — assume the credentials it had access to are exposed. - Rotate everything. GitHub PATs, AWS access keys, GCP service-account keys, Azure SPs, npm publish tokens, PyPI tokens, Hugging Face tokens, OpenAI / Anthropic API keys. All of them. Don’t try to figure out which ones the malware actually grabbed; assume all of them.
- Check for the persistence files. In any repo that ran the bad version, look for
.claude/settings.local.jsonor.vscode/tasks.jsonchanges you didn’t make. Diff against git history. Anything new is suspicious. - Check GitHub Actions workflows. Compare
.github/workflows/in your repos against last week’s commit log. Look for any workflow you didn’t add, especially ones that echo or POST environment variables. - Pin
lightningto a known-good version (2.6.1 or earlier, or 2.6.4+ once a clean release ships) in yourrequirements.txt/pyproject.toml, with a hash.pip install --require-hashesin CI prevents future hijacks where the version number stays the same but the file content changes. - Check your .npm and PyPI publish tokens. If you’re a maintainer with a token in
~/.npmrcor~/.pypirc, those are the prize the worm wants. Rotate, and consider moving to OIDC-based publishing (GitHub Actions trusted-publishing) so there’s no long-lived token on disk at all.
The deeper trend
The Python / AI ecosystem has been operating on the assumption that “npm has a supply-chain problem; we don’t.” That was never true on the merits — it was true because attackers hadn’t gotten serious about PyPI yet. Two things shifted recently to invite their attention:
- The credentials AI/ML developers have on their machines are now valuable in their own right — OpenAI, Anthropic, AWS Bedrock keys, model-weight S3 buckets. Not just stepping stones to other targets.
- Dev tools (Claude Code, Cursor, Copilot) read local repo state and trust it. That’s a new persistence vector that didn’t exist three years ago. The malware took advantage of it elegantly.
Expect more of these. PyTorch Lightning won’t be the last AI training library to be hijacked, and the hijack model will refine. The defensive answer isn’t “don’t use Python AI libraries.” It’s the same hygiene that’s been preached for npm for years, applied a generation later: pin versions with hashes, separate publish tokens from runtime credentials, treat every fresh pip install in a long-lived environment as a potential breach.
Source: Semgrep’s research disclosure of the malicious lightning 2.6.2 / 2.6.3 PyPI release.
Photo: Code on dark monitors by Tima Miroshnichenko on Pexels.
