






















Socket proactively blocks malicious open source packages in your code.
Secure your dependencies with us
The popular PyPI package lightning has been compromised in a supply chain attack affecting newly published versions of the package.
Socket has classified lightning versions 2.6.2 and 2.6.3 as malicious. Version 2.6.1, published on January 30, 2026, is clean. Version 2.6.2, published on April 30, 2026, introduced malicious code into the legitimate library. Socket’s AI scanner flagged both versions 2.6.2 and 2.6.3as potentially malicious eighteen minutes after publication.
The compromise affects a widely used deep learning framework for training, deploying, and shipping AI products. According to PyPI download statistics, lightning receives hundreds of thousands of downloads per day and millions of downloads per month, making this a high-impact incident for Python AI and machine learning environments.
The malicious package includes a hidden _runtime directory containing a downloader and an obfuscated JavaScript payload. The execution chain runs automatically when the lightning module is imported, requiring no additional user action after installation and import.
Socket’s analysis found:
start.py, which downloads and executes Bun, a JavaScript runtime, from GitHubrouter_runtime.js, an 11 MB obfuscated malicious payloadThe obfuscated JavaScript payload contains many similarities to the Shai-Hulud attacks, overlapping in targeted tokens, credentials and obfuscation methods. Socket also identified signs that router_runtime.js both poisons Github repositories and infects developer npm packages.
The obfuscated JavaScript payload contains 703 references to process and env, more than 463 references to tokens and authentication, and 336 references to repositories. Socket also identified credential exfiltration patterns consistent with theft of developer and cloud credentials.
An initial public report also surfaced in Lightning-AI’s GitHub repository in issue #21689, titled “Possible supply chain attack on version 2.6.3.” That report described a hidden execution chain that downloads Bun and runs an 11.4 MB obfuscated JavaScript payload when lightning is imported. The issue was later closed without public explanation, which leaves the maintainer response unclear at the time of writing.
Socket also opened a follow-up issue in the Lightning-AI/pytorch-lightning repository warning that versions 2.6.2 and 2.6.3 were compromised. The issue was closed within one minute by the pl-ghost account, which then posted a “SILENCE DEVELOPER” meme in the thread. This behavior indicates that the project's GitHub account appears to be compromised, though Socket has not yet confirmed the full scope of maintainer account access involved in the attack.


The account's behavior today is very suspicious. In addition to closing the two disclosure issues, pl-ghost performed six create-and-delete branch operations across multiple Lightning-AI repositories in roughly 70 minutes. Four of those branches used random 10-character lowercase names, a pattern associated with the Shai-Hulud worm's write-access probing. A fifth branch, dependabot/fix-deds, attempted to impersonate Dependabot but used a misspelled "deds" and the wrong namespace separator: Lightning-AI's actual Dependabot configuration uses a dash prefix, not a slash. Every branch was deleted within seconds of being pushed, with no associated workflow runs.
The disclosure suppression, branch-creation patterns matching a known worm, and clumsy Dependabot impersonation strongly indicate that the pl-ghost account is compromised, likely by the same actor that published the malicious wheels. This is consistent with a single set of stolen credentials being used both to publish to PyPI and to suppress the inbound disclosure on GitHub.
The pl-ghost account appears to have been used to probe other Lightning-AI repositories during the same incident window, suggesting attempted lateral expansion beyond the compromised lightning PyPI package. According to the analysis, four short-lived branches were pushed and deleted across Lightning-AI/litAI, Lightning-AI/utilities, and Lightning-AI/torchmetrics between 12:40Z and 13:44Z. Each branch existed for no more than one second, none touched the default branch, and none triggered GitHub Actions workflows. Three branch names used random 10-character lowercase strings, similar to the Shai-Hulud npm worm’s credential-verification pattern, while a fourth impersonated Dependabot with a typo: dependabot/fix-deds. The account reportedly has no prior commit history in those repos, which makes the activity a clear behavioral break from its normal use.
The attempted expansion appears to have failed because Lightning-AI’s repository controls blocked the path from GitHub access to malicious package publication. Branch protection, required status checks, tag-gated PyPI publish workflows, and likely workflow approval prevented the attacker from landing code on default branches or triggering release workflows. The analysis suggests the successful lightning upload likely came through a separate PyPI credential path, probably a project-scoped PyPI token for lightning, while the pl-ghost GitHub credential was used to test whether the attacker could reach other repos and potentially expose additional package tokens through workflow execution. In short: the attacker had a working path to publish malicious lightning releases, but the observed attempts to pivot into other Lightning-AI packages appear to have stalled before payload delivery or CI execution.
Socket recommends blocking lightning versions 2.6.2 and 2.6.3 immediately. Any environment that installed and imported either version should be treated as compromised.
Recommended immediate actions:
lightning versions 2.6.2 and 2.6.3 from affected systems.2.6.1, or wait for confirmation from the maintainers before upgrading.Socket is continuing to analyze the package, payload behavior, indicators of compromise, and potential connections to recent large-scale open source supply chain attacks. We will publish a deeper technical analysis as more details are confirmed.
The attacker also posted an onion link in the GitHub issue thread http[://22]evxpggnkyrxpluewqsrv5j4jtde6hut2peq3w44d6ase676qlkoead[.]onion, pointing to a Team PCP-branded site hosted on Tor. The landing page uses an animated interface with music and a “click to start” prompt. After clicking through, the site links to a text announcement presented as a PGP-signed message.

The message identifies the group as “TEAM PCP” and claims the operation is connected to broader extortion and data-leak activity. It includes statements about Vect, CipherForce, Checkmarx leaks, and LAPSUS$, including a claim that LAPSUS$ is “a good partner” and has been “involved heavily throughout this entire operation.” The message also lists contact channels on SimpleX, Session, TOX, a Breached forum profile, and the same Tor site.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512Hello everyone, T here there are a few team announcements.
STATEMENT ON VECT:
Given the recent vulnerabilities discovered in the Vect locker, I find it important to say,
we have never used Vect encryption tools and we own CipherForce, our own private locker,
which dozens of victims have recovered files using, our partnership with them has always been for their negotiation team.
We have been working with a lot of other groups. So if they do not fix this we will cease to give them any more data/access.RECENT DEPLATFORMING:
Our friendship is temporarily ended with X while they sort their unfair ban out, but we are back and operating.
Announcements will be posted to this .txt for now, although we will likely reboot CipherForce in the near future and host the blog here again.CHECKMARX LEAKS & LAPSUS$:
The LAPSUS$ group you see leaking checkmarx data is a good partner of ours and has been involved heavily throughout
this entire operation. We are not beefing with them, they have not stolen from us. We are in alliance working side by side.ONLY Socials Below:
SimpleX: https://smp15.simplex.im/g#1eF0NSovWk6C5NugAjpbcNHk_aw_GJo49k_lkpdiQRw
Session: 05a04c7c548c39e903c5913973dd55b6f3d9c1a10d346ca9d49d10b9428095823e
TOX: BA8D312391E2E379144046841FC97EDF1DD2D400E3AB3B3DAAF08D8569AE2D43AB997A5069F2
ONLY FORUM PROFILE: https://breached.st/members/teampcp.336107/
TOR SITE: http://22evxpggnkyrxpluewqsrv5j4jtde6hut2peq3w44d6ase676qlkoead.onion/
(We are more open to interviews now that everyone has settled, from based individuals only ofc.)DO NOT TRUST ANYONE speaking on behalf of the team without proper cryptographic verification.
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEEghIdLGWyOzy1VwRKheSnHdtEm1gFAmnw+l4ACgkQheSnHdtE
m1hopA//TEeT3KKwXKGV605Z0epeNnaIbgc+JfMmIdyDy6yfDDvjGtfbX6OtxQNm
gHzOnppwClHJ9RJAff2WjTgR3Hepcu69BCpwXq31kDZjE0Fz1zLKW4yzF/89xtgz
dLj3RQ27YQ7m7o2GMIekYM7leZiZQSGUVohUyyM2VOEIGtnDJsh0CxZ/bkumXEOg
WEQ9gqHT/vT6sJoYGT3KJeQTRaaXexbP6u0CUIbQ8jclbmOAaGwyKKELFo7yWCm3
qiqVv9TXfgFlRGLBspTbDRqcaiVYfVD6b5zTkaDVGfNuKq1j0lUEwyK4rcmeytQ2
pgVJ6gGmfAdZLuzeyR1cdu/IXzebSSsQR+iDuUejxS04Y99CC9sDzoMDTwZc6E6Z
0hh5otdipDAF7oF6Owq2i+KOV167PgtEgtYIgSRdYHilw2qhRYjPz4J6xVLm+q/B
Y0/Gz7AKWG1ht4MRbP6wpQpFzqxYgP4Htm0OP32+sb57m0uaO/8kIorwa9TXnbYX
wul6BFFc5ajS7OF67gQOuG13Fvm/toQA9AJit5znPRkyb1U0Q5caoqtgJD10P3as
8MPWMEMpVkzTMmQm+ToDyROCQgI885KBFuovut7QsR1ZFaLE75XlBcTXb8itsdu3
FQfKoE469GIMhaBlOpLYs0vWFuJCD3JdUWRuRd/4/HFIziyftz8=
=8Z4y
-----END PGP SIGNATURE-----
Socket has not yet verified the authenticity of the PGP signature or independently confirmed the claimed relationships between Team PCP, LAPSUS$, Checkmarx-related leaks, Vect, or CipherForce. However, the onion link was posted directly in the GitHub issue thread during the incident response window, alongside other signs of apparent maintainer account compromise.
The post, combined with the malware’s credential theft behavior and GitHub abuse patterns, suggests the attackers may be attempting to publicly associate the lightning compromise with Team PCP or related extortion activity.We are continuing to investigate whether the Team PCP reference reflects true attribution, opportunistic branding, or a false-flag attempt.
javascript-obfuscator (obfuscator.io)._0x3cc578(index)), which resolves hex indices into strings from a rotated array at runtime.__decodeScrambled(), handles strings that require AES-based decryption on top of the array lookup.globalThis at startup, making it available to any co-loaded module.// Obfuscator bootstrap pattern
const _0x3cc578 = _0x2064;
(function(_0xe9331d, _0x47a657) {
while (true) {
try {
const _0x9b03ff = parseInt(...) / 0x1 + ...
if (_0x9b03ff === _0x47a657) break;
else _0x2a4de5['push'](_0x2a4de5['shift']());
} catch(_0x48b1a1) {
_0x2a4de5['push'](_0x2a4de5['shift']());
}
}
}(_0x10ee, 0x4ec1a));
// Secondary decryptor exposed globally
globalThis[_0x3cc578(0xb0c2)] = Iy; // resolves to "__decodeScrambled"Bun.gunzipSync, Bun.write, and Bun.file directly.The first component is a credential scanner registered under the internal type string 'runner'. It applies four regex patterns against accessible token material:
{
'ghtoken': /gh[op]_[A-Za-z0-9]{36,}/g, // GitHub OAuth / Personal Access tokens
'npmtoken': /npm_[A-Za-z0-9]{36,}/g, // npm access tokens
'ghsjwt': /ghs_\d+_[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, // GitHub App JWTs
'ghs_old': /ghs_[A-Za-z0-9]{36,}/g // legacy GitHub App installation tokens
}Beyond scanning in-process memory, the harvester queries cloud credential endpoints directly:
http://169.254.169.254 and the ECS credential endpoint at http://169.254.170.2 to steal instance role credentialsAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYAZURE_TENANT_ID and the Azure CLI token cachehttps://oauth2.googleapis.com/tokeninfoThe harvester also checks process.env.GITHUB_ACTIONS and twenty other CI-platform environment variables to determine whether it is running inside a pipeline — a high-value context where long-lived deployment credentials are typically available:
// CI environment detection (excerpt)
if (process.env.GITHUB_ACTIONS) return true;
if (process.env.CIRCLECI) return true;
if (process.env.CODEBUILD_BUILD_ID) return true;
if (process.env.VERCEL || process.env.NOW_GITHUB_DEPLOYMENT) return true;
// ... 17 additional platformsEach discovered token is validated against https://api.github.com/user before being passed downstream, ensuring only live credentials are acted upon. npm tokens are cross-referenced against https://registry.npmjs.org/-/whoami.
Validated GitHub tokens are passed to the _G class, which implements an automated repository backdoor using the GitHub GraphQL API.
For each stolen token, the worm fetches up to 50 branches from every repository the token can write to:
// Plaintext log string recovered from obfuscated bundle
"Fetching branches for " + this.owner + "/" + this.repo + " …"
"Pushing [N] file(s) [...] to [N] branch(es) …"It filters branches against a configurable exclusion list (AH0, empty by default) before targeting all remaining branches.
The worm commits a fixed file payload (k4f) to every targeted branch using createCommitOnBranch — GitHub's GraphQL mutation that accepts file additions.
The operation is an upsert: it creates files that do not yet exist and silently overwrites files that do. No pre-check for existing content is performed.
const k4f = {
'.vscode/tasks.json': _4f, // VS Code tasks backdoor
'.claude/router_runtime.js': { sourcePath: Bun.main }, // self-copy
'.claude/settings.json': x4f, // tampered Claude Code settings
'.claude/setup.mjs': zT, // obfuscated setup script
'.vscode/setup.mjs': zT, // same script, VS Code path
'.github/workflows/format-check.yml': // GitHub Actions workflow
};The .claude/router_runtime.js entry uses Bun.main as its source path — the worm copies itself verbatim into the target repository, ensuring the next developer to clone the repo receives the full payload.
Every poisoned commit is authored using a hardcoded identity designed to impersonate Anthropic's Claude Code:
// Committer identity (email recovered in plaintext from paired file)
{ name: 'claude', email: 'claude@users.noreply.github.com' }The commit body is also constructed to include Co-authored-by: claude <claude@users.noreply.github.com> trailers, causing GitHub's UI to surface "claude" as a contributor on the repository. To a developer scanning a git log or a PR timeline, the commit is visually indistinguishable from a legitimate Claude Code action.
The commit loop retries up to 2 times per branch with per-attempt callbacks, logging successes and failures internally. All logging calls are assigned to no-op functions, so execution is fully silent.
The Wq class implements a second propagation vector targeting the developer's local npm packages. For each .tgz tarball it locates:
package.jsonsetup.mjs (the same zT payload planted in repositories) into the package rootpackage.json to add a postinstall hook pointing to node setup.mjsmajor.minor.patch+1)// Recovered plaintext from Wq class
'node setup.mjs' // injected postinstall command
'setup.mjs' // payload filename
'utf-8' // encoding for package.json writeThe version bump is deliberate: when the developer next publishes from their local environment, the tampered package is newer than the current registry version and will be accepted as a legitimate update. Every downstream user who installs it will execute setup.mjs at install time.
The content of setup.mjs (zT) is stored as a gzip-compressed, base64-encoded blob embedded in the string array and decoded at runtime via Bun.gunzipSync. Its full behavior has not yet been statically recovered due to the nested encoding, but its role as a postinstall hook in the npm worm chain places it as the third-generation payload.
router_runtime.js shares a broad attack category with the Shai-Hulud npm worm (credential theft → GitHub repo poisoning → npm package propagation), but differs in key ways:

No Shai-Hulud IOCs (SHA1HULUD, OhNoWhatsGoingOnWithGitHub, discussion.yaml) appear in the file. This is assessed to be a distinct actor employing a similar playbook with a different social-engineering angle — impersonating a widely-trusted AI coding tool rather than using recognizable campaign branding.
router_runtime.js is present in .claude/ in any repository you maintain, treat that repository as compromised. Audit all branches for unauthorized commits from claude@users.noreply.github.com..tgz files) in your build environment for unexpected postinstall entries and version bumps not reflected in your source control..github/workflows/format-check.yml.router_runtime.js
5f5852b5f604369945118937b058e49064612ac69826e0adadca39a357dfb5b1f1b3e7b3eec3294c4d6b5f87854a52471f03997f40d0f21b64ec8fb3a7a1959897252e09.claude/router_runtime.jshxxp://169[.]254[.]169[.]254hxxp://169[.]254[.]170[.]2此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。