top of page

A Worm in an AI-Agent SDK Went Looking for .claude and .cursor. Revoke the Stolen Token Too Early and It Wipes Your Home Directory.

Writer: Patrick Duggan
Patrick Duggan
7 hours ago
4 min read

At 01:12 UTC on October 8, someone published version 0.5.144 of tensorlake, the official TypeScript SDK for an AI document-ingestion platform used to build agents. It carried a member of the Shai-Hulud worm family. Eight minutes later SafeDep flagged it. Eleven minutes later Socket did. The version is gone from npm now, and 0.5.143 is clean. If you installed it in that window, the order in which you clean up decides whether you keep your home directory.



What the payload does


Credit for the analysis belongs to Socket and SafeDep, with further write-ups from Endor Labs and Aikido. Here is what they found.


A preinstall hook runs lib/setup.mjs, which uses the Bun runtime to launch an obfuscated payload called Math_Symbol.js. That payload steals npm tokens, GitHub tokens, AWS credentials (including from the instance metadata service, Secrets Manager and SSM), HashiCorp Vault and Kubernetes credentials, SSH keys, .env files and crypto wallets.


It also takes the configuration and MCP files for Claude, Cursor, Kiro, Windsurf and Zed. That is the line that matters for anyone building with AI agents. Those files are where agents keep the keys and server definitions that let them act: the connection strings for the tools an agent may call, and often the tokens that come with them. A developer's agent config is a map of everything their agent can touch.




Then it spreads. It lists every package the victim can publish, builds fresh Sigstore provenance for each, and republishes them with the worm inside. The provenance is real, because it was generated by the victim's real identity. A green provenance badge on a package tells you who published it, not whether that person was compromised.



The trap: revoke first and it wipes


This is the part that changes incident response. The payload installs a watcher, named gh-token-monitor, as a scheduled task on Windows, a systemd service on Linux and a LaunchAgent on macOS. It checks the stolen GitHub token every 60 seconds for 24 hours. If GitHub starts rejecting the token, which is exactly what happens when you revoke it, the watcher deletes the user's home directory. SafeDep quotes the commands: rm -rf on the home directory on Unix, and Remove-Item on the user profile on Windows. The code even carries the string IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner, which earlier Shai-Hulud waves also used.


So the reflex every security team has drilled, rotating the stolen credential immediately, is the trigger. The attacker has turned your first correct move into the destructive one.





Clean up in this order


Socket's remediation guidance is the one to follow. In short:


First, block 0.5.144 in every manifest and lockfile. Second, find every host where the install scripts ran: developer laptops, CI runners and build containers. Third, isolate those hosts, and take an image first if you will want forensics. Fourth, remove the watcher: the gh-token-monitor scheduled task, systemd service or LaunchAgent. Only then, fifth, revoke and replace credentials: npm, GitHub, cloud, Vault, Kubernetes, and the keys inside your agent and MCP configs. Sixth, rebuild from a trusted source and audit what the stolen tokens could reach while they were live.


If you cannot be sure the watcher is gone, take the machine offline before you revoke. A wiped laptop that was already isolated costs you a rebuild. A wiped laptop that was still syncing to a shared drive can cost more.



Where the command channel lives


There is no hardcoded command server to block in the usual way. The payload looks up its endpoint by reading an Ethereum smart contract, through about 30 public RPC endpoints, with a GitHub fallback. SafeDep names the contract as 0xb614155Fd88114d40549b259457Bcf921Df091B9 and the resolved C2 domain as iseekaigogo.com, on port 443 with the paths /router and /hbd/. The domain was registered on September 21 and sits behind Cloudflare.


This is the same move as ChainDrop, which we covered in August when it took 444 npm packages and read its C2 from an Ethereum contract: ChainDrop Took 444 npm Packages With 2 Billion Monthly Downloads. Socket ties the loader and payload file names directly to the August ChainDrop and Shai-Hulud compromises of keyv and cacheable. The contract is new, though. ChainDrop's was 0xE1f2395ee43e45A1556EC6438a88c31B83493103. A new contract on the same pattern is a new dead-drop, so a blocklist built in August does not cover it.



What we had, and what we added


We checked our own estate first. tensorlake is not in any of our lockfiles, package manifests, node_modules, Python environments or npm cache. We were not exposed.


In our feed, the two payload hashes (setup.mjs and Math_Symbol.js) were already present by October 8, via ThreatFox. That is a third-party feed, so it is corroboration, not something we found. The package name was in via the OSV malicious-package feed, also third party. The C2 domain and the new Ethereum contract were not in the feed. We added both today at confidence 85, attributed to SafeDep and Socket's research, and verified each write by reading it back. We added the domain only. The Cloudflare IP addresses in front of it serve thousands of unrelated sites and do not belong on a blocklist.



Why an AI-agent SDK is the right target


An SDK for building agents gets installed by exactly the people whose machines hold the most useful keys: developers wiring agents into production systems. The worm does not need to know what Tensorlake does. It only needs one publisher token to land on a machine where .claude and .cursor sit next to .npmrc.


In August, ChainDrop went after the shared JavaScript plumbing underneath everything. This wave hit an SDK that people use to build agents, with a payload that already knows which agent config folders to read. If you run coding agents on the same machine where you publish packages, those two facts now sit one preinstall hook apart. Keep publish tokens off agent workstations, require two-factor approval on npm publishes, and treat your agent's config folder like an SSH key directory, because the attackers already do.


Was this useful? Rate this post. The widget is at the bottom of the page, and we read every response.




Every indicator in this post is in the feed. Free.

1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.



Was this useful? Thirty seconds, no cookies, no tracking, no third parties, your address hashed and never stored. If the box below does not load, the same question lives at https://analytics.dugganusa.com/nps.html?post=tensorlake-npm-shai-hulud-steals-ai-agent-config-wipe-on-revoke



Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page