The Shai-Hulud npm worm has now reached AI infrastructure. On October 8, tensorlake@0.5.144, the npm SDK for Tensorlake’s platform for running AI agents and untrusted AI-generated code, shipped with the worm’s credential-stealing payload inside. The jump matters because the SDK installs on developer workstations and build runners, outside the sandbox protections the platform itself sells.
What happened, on the clock
Socket’s write-up has the timeline. The malicious release went out at 01:12 UTC and Socket flagged it 11 minutes later. The payload rode in through a preinstall hook running lib/setup.mjs, an obfuscated Bun-based loader, with Math_Symbol.js doing the credential theft and self-propagation.
The setup is worse than a straightforward token grab. Attackers pushed commits directly to the main branch of the tensorlakeai/tensorlake repository under a maintainer’s identity, then published through the project’s own release workflow. That means the tarball carried a valid npm provenance attestation. The lesson everyone keeps having to relearn: provenance proves where a build came from, not that the code is safe. A policy that allows anything with valid provenance would have passed this release.
What it steals
The harvest list is long. StepSecurity’s analysis documents npm and GitHub tokens, AWS credentials pulled from IMDS, ECS, Secrets Manager and SSM, HashiCorp Vault secrets, Kubernetes service-account tokens, SSH keys, .env files, crypto wallets, browser data, and the configuration and MCP files of AI coding tools including Claude, Cursor, Kiro, Windsurf and Zed. That last category is new-ish and pointed: AI agent config files hold API keys, and some of them can re-trigger execution when a project opens.
Exfiltration went to a public GitHub repo created in the victim’s own account, described “Shai-Hulud: Here We Go Again”, with a fallback to the domain iseekaigogo.com. The command-and-control endpoint is resolved through an Ethereum smart contract via public RPC endpoints, the so-called EtherHiding technique, so there is no hardcoded C2 to blocklist.
The nastiest bit is the dead-man switch. The payload installs a gh-token-monitor persistence service that polls the stolen GitHub token every 60 seconds for up to 24 hours. If the token gets revoked, it deletes the user’s home directory. So the standard first move in incident response, rotate everything, is exactly the wrong first move here.
Where this worm came from
Shai-Hulud first appeared on September 15, 2025 as the first known self-replicating worm operating at scale in npm, compromising hundreds of packages including @ctrl/tinycolor. A second wave in late November 2025 hit more than 700 packages and generated over 27,000 malicious GitHub repositories. An August 2026 wave called ChainDrop compromised keyv and flat-cache using the same setup.mjs loader pattern seen in Tensorlake. This family keeps evolving while keeping the core recipe: compromise a maintainer credential, steal tokens, and republish through the victim’s own publishing rights.
Tensorlake’s response was reasonably quick. npm removed 0.5.144, maintainers reverted the malicious source through pull request #1016, and shipped 0.5.145. Version 0.5.143 is the last known-good release. PyPI and Cargo distributions showed no compromise. Six companion tensorlake-native-* packages published in the same run carried no payload but are treated as affected.
What to actually do
If you have this package anywhere, assume every credential on that machine is burned. The order of operations is unusual and important:
- Check for tensorlake@0.5.144 in lockfiles and with npm ls, plus the tensorlake-native-* companions. Also grep for .claude or .vscode files you did not create and GitHub commits from claude@users.noreply.github.com.
- Remove the gh-token-monitor persistence before touching credentials. On Linux, systemctl –user disable –now gh-token-monitor.service and delete ~/.config/gh-token-monitor/. On macOS, unload the LaunchAgent com.user.gh-token-monitor.plist. On Windows, delete the ONLOGON scheduled task running monitor.ps1.
- Only then rotate npm, GitHub, cloud, SSH, Kubernetes, Vault and wallet credentials, plus any AI tool or MCP tokens on the host.
- Pin to 0.5.143 or upgrade to 0.5.145, delete node_modules, and run npm cache clean –force.
- Set ignore-scripts=true in .npmrc by default and review any package that needs install hooks.
Socket published SHA-256 hashes for setup.mjs and Math_Symbol.js worth adding to endpoint detection.
The part that should worry npm users most
The loader deliberately skips CI environments. That concentrates the blast radius on developer laptops, which hold agent configs, browser password stores and wallet extensions. Registries have been shipping mitigations, granular tokens, trusted publishing, provenance, and none of them helped here because the attack came in through the repo itself, signed and attested by the project’s own pipeline. The integrity controls that would have caught this are upstream: branch protection, signed commits, and a required second reviewer on anything that can trigger a publish. Tensorlake added exactly those in its hardening pass.
Long-lived tokens on dev machines remain the root cause of every wave of this worm. Until that changes, the defense is boring and local: fewer secrets on laptops, install scripts off by default, and a healthy suspicion of any release that arrives with more provenance than scrutiny.