Supply chain
tensorlake 0.5.144 on npm carried a Shai-Hulud worm
A hijacked tensorlake npm release ran a credential-stealing worm at install. Who is affected, how it spreads, the IOCs, and the safe cleanup order.
On October 8, 2026 at 01:12 UTC, version 0.5.144 of tensorlake, the npm SDK for Tensorlake's AI agent sandbox platform, was published with a new build of the Shai-Hulud worm inside. The package gets about 12,000 downloads a week. Its preinstall script runs the malware the moment npm install resolves that version, so nobody has to import the SDK or start an agent. Socket flagged it about 11 minutes after publication, npm removed it, and Tensorlake released a clean 0.5.145.
If any laptop, build server or container installed tensorlake@0.5.144, treat it as compromised and every credential it could read as stolen. The cleanup order matters here: this variant plants a watcher that wipes the user's home directory if the stolen GitHub token is revoked while the watcher is still running. Tensorlake's PyPI and Cargo packages showed no sign of tampering at the time of the reports.
How it got into the package
The attack started in Tensorlake's GitHub repository. According to SafeDep and Aikido, an attacker made commits to tensorlakeai/tensorlake under a maintainer's identity starting at about 01:20 UTC on October 7, added the two payload files and the install hook, bumped the version to 0.5.144 and set off the project's own publishing. The repository was in the attacker's hands for roughly a day before the npm release. The two firms cite different commit IDs, so check the repository history yourself rather than relying on one list.
Because the release came through the project's normal pipeline, it looked like any other patch version to a lockfile update or a Dependabot pull request.
How it works
The package.json in 0.5.144 contains "preinstall": "node lib/setup.mjs". npm runs lifecycle scripts like this automatically during install unless scripts are disabled. setup.mjs is an obfuscated loader: it downloads the Bun JavaScript runtime and uses it to run lib/Math_Symbol.js, the main payload. Aikido notes the payload sets a global WORMTAG marker before it unpacks, and OX Security and SafeDep both give its value as tensrlake, a misspelling that makes a handy search string.
The payload then goes after almost every secret a developer machine or runner holds:
- npm tokens from
.npmrc, GitHub tokens (checked for repository and workflow scope), SSH keys and.envfiles. - AWS credentials, including calls to the instance metadata service, Secrets Manager and SSM Parameter Store.
- HashiCorp Vault tokens (including a local agent on
127.0.0.1:8200), Kubernetes service-account tokens and kubeconfig files. - AI coding tool configuration for Claude Code, Cursor, Kiro, Windsurf and Zed, including MCP server files, which often hold API keys.
- Crypto wallet files and browser wallet extensions. Browser passwords are pulled by a separate HackBrowserData binary fetched from the attacker's server.
Stolen data goes to iseekaigogo[.]com. If that domain is down, the worm reads a replacement from an Ethereum smart contract, 0xb614155Fd88114d40549b259457Bcf921Df091B9, through public RPC nodes. A blockchain record is hard to take down, which is why this "dead drop" design keeps reappearing. Researchers also describe public GitHub repositories, created with stolen tokens and described as "Shai-Hulud: Here We Go Again", used as a last-resort drop for encrypted data.
How it spreads
With a stolen npm token, the worm lists every package that identity can publish, injects its loader and preinstall hook, bumps the patch version and republishes. Socket and SafeDep both report that it also creates provenance signatures, so a provenance badge on a new release is no proof that the release is clean.
With a stolen GitHub token, it commits hook files for Claude Code and VS Code into the victim's repositories (OX Security lists .claude/settings.json and .vscode/tasks.json), so the next developer who opens the project in either tool runs the loader. It also plants a workflow posing as a Copilot or Dependabot job that dumps repository secrets. Nobody has published infection counts yet.
Socket and The Register tie the code to the "ChainDrop" Shai-Hulud wave that hit keyv and related packages in August. OX Security points out that the public keys embedded in this build are new and suggests a new group may be reusing the Shai-Hulud name. No attribution has been confirmed.
The dead-man switch
The payload installs a watcher called gh-token-monitor: a systemd user service on Linux, the LaunchAgent com.user.gh-token-monitor on macOS, or a scheduled task running monitor.ps1 on Windows. It polls the GitHub API with the stolen token. When GitHub starts rejecting the token, it deletes the home directory (rm -rf ~/ or Remove-Item $env:USERPROFILE -Recurse -Force). The code carries the string IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner. Revoking the token from a different machine still triggers it, because the check runs on the infected host.
What to do
- Find every install. Search lockfiles and build logs for
tensorlake0.5.144, for examplegrep -rn '"tensorlake"' --include=package-lock.json --include=pnpm-lock.yaml --include=yarn.lock .and then confirm the resolved version. Pin to 0.5.145 or later. Also check container images built on October 8 or after. - Isolate affected hosts from the network. Removing the npm package does not remove the implant.
- Remove the watcher before revoking anything. On Linux run
systemctl --user disable --now gh-token-monitor.serviceand delete~/.config/gh-token-monitor/,~/.local/bin/gh-token-monitor.shand~/.config/systemd/user/gh-token-monitor.service. On macOS runlaunchctl unload ~/Library/LaunchAgents/com.user.gh-token-monitor.plistand delete the file. On Windows delete thegh-token-monitorscheduled task and%LOCALAPPDATA%\gh-token-monitor. - Then rotate GitHub and npm tokens, AWS keys, Vault and Kubernetes tokens, SSH keys, AI tool API keys and anything in
.envfiles on those hosts. Move wallet funds from any wallet that was on the machine. - Hunt for spread. Look at your npm packages for unexpected patch releases since October 8, and at your GitHub organization for new public repositories described as "Shai-Hulud: Here We Go Again", unfamiliar workflow files, and commits adding
.claude/settings.jsonor.vscode/tasks.json. Blockiseekaigogo[.]comand look for past DNS lookups of it. - Rebuild affected machines and runners from a known clean image before giving them secrets again.
File indicators, from Socket, Aikido and SafeDep: lib/setup.mjs SHA-256 25a0735d0db7dc40e5d45ce42d9c106067e6a66e184d967cfecfab17c3bcb5ef and lib/Math_Symbol.js SHA-256 b50a00900399ba99fb6ce1fc151519cb99d44320ef2a631f2237e1aea0ad6fec. Hashes change whenever a payload is rebuilt, so also search for the file names, the tensrlake marker and a Bun binary on machines that never installed it.
The wider lesson
Install scripts run with the full rights of whoever types npm install, on machines that hold the most valuable credentials in the company. Setting ignore-scripts=true in a project or user .npmrc, and allowing scripts only for the few packages that need them, would have stopped this payload from running. A short delay before adopting brand-new versions in CI covers the window between publication and detection, which here was minutes but is often days.
Our cloud and Kubernetes security work covers how CI runners and build secrets are scoped, and our red team and code review engagements test what a single stolen developer token can reach. Open the chat and Yaali, our AI agent, will pass your question to an engineer.
Sources: Socket, Aikido, SafeDep, OX Security, The Register, Techzine, GBHackers.