TRENDING
Rows of identical brass-colored apartment mailboxes with small locks and name labels along an orange corridor wall
October 9, 2026
How to Prevent Broken Object Level Authorization (IDOR) in a FastAPI App
Street-level upward view of the Monetary Authority of Singapore building and neighbouring office towers under a pale sky
October 9, 2026
Singapore’s AI Guidelines Turn Independent Review Into a Question of Who Sets the Risk Rating
Cast-iron late Qing dynasty coin minting press with a large flywheel, displayed in a museum case
October 9, 2026
Attackers Hijacked the .gh, .sl and .as Country Domains and Minted HTTPS Certificates for Google
Rows of closed oak library card catalog drawers, each with a brass pull and a blank label holder
October 9, 2026
How to Encrypt PII in Python and Keep It Searchable With Blind Indexes
Close-up of a vintage Western Electric manual telephone switchboard with orange lamps, red patch cords plugged into jacks, a rotary dial and a black handset
October 9, 2026
Microsoft’s Agent Lightning v1.0 Turns Agent Training Into a Sample-Accounting Problem
09 Oct 2026
SXZ.io SXZ.io
  • Home
Search the Site
Popular Searches:
Technology Amazon AI
Recent Posts
Two orange safety relief valves on grey pressure vessels in an industrial plant
How to Add Backpressure and Load Shedding to a Python Service Before Overload Takes It Down
October 8, 2026
Yellow diamond-shaped merging traffic warning sign showing a side road joining a main road
GitHub’s Git Rebuild Turns Repository Durability and Read Scale Into Two Separate Problems
October 8, 2026
A lugworm lying on wet sand and mud at low tide
A Compromised Admin Account Put the Shai-Hulud Worm Into AI Sandbox Maker Tensorlake’s npm SDK
October 8, 2026
SXZ.io SXZ.io
  • Home

Categories

Articles 232 Posts
News 234 Posts
Learning Hub 204 Posts
Home/News/A Compromised Admin Account Put the Shai-Hulud Worm Into AI Sandbox Maker Tensorlake’s npm SDK
News

A Compromised Admin Account Put the Shai-Hulud Worm Into AI Sandbox Maker Tensorlake’s npm SDK

A poisoned Tensorlake SDK release reached npm through the project’s own release workflow with valid provenance, carrying a worm whose tripwire can wipe a home directory when a stolen GitHub token is...

October 8, 2026 7 Min Read
7

Tensorlake provides isolated sandboxes for running untrusted, LLM-generated code. At 01:12:07 UTC on October 8, 2026, a poisoned build of its npm SDK, [email protected], went live carrying the credential-stealing Shai-Hulud worm. Socket flagged the release 11 minutes later, SafeDep flagged it at 01:20 UTC, and npm has since removed it. The Register reports that the package draws roughly 12,000 downloads a week, but none of the analyses behind this story says how many machines installed the bad version.

Table Of Content

  • What happened, hour by hour
  • A clean-looking release with valid provenance
  • What the payload does
  • Who was actually exposed
  • What to do now
  • Indicators to search for
  • What is still unknown

How it got there matters more than the package. Tensorlake’s own revert pull request says the payload was “committed directly to main by a repo-admin account through the GitHub web UI” and then released by manually dispatching the project’s publish workflow, which “built and signed it with Sigstore provenance.” SafeDep adds that the attacker “did not need an npm token.” The result passes any check that asks only who built the package. It is the same shape as the keyv compromise we covered in August, when Microsoft named the worm ChainDrop, now aimed at tooling that AI agent developers install.

What happened, hour by hour

All times are UTC. Commit times come from GitHub’s API for the 13 commits between Tensorlake’s last clean commit and the final poisoned one, and publish times come from the npm registry’s own time log.

When What happened
Oct 6, 21:59 npm 0.5.143 is published. Its provenance record names commit 52f19c8a, which Tensorlake calls the last clean commit.
Oct 7, 01:20 The first poisoned commit, titled “Add files via upload”, adds the loader and payload files. A preinstall hook follows at 01:24, and SafeDep says the 01:43 commit repaired the JSON that edit broke. Four more uploads follow, the last at 03:44.
Oct 7, 03:57 to 23:41 Six more commits, most of them bumps to version 0.5.144 and fixes to the platform packages’ version numbers.
Oct 8, 00:08 The release workflow, publish_npm.yaml, is started by hand, according to SafeDep. The provenance record shows a workflow_dispatch trigger.
Oct 8, 00:17 to 00:19 Six platform packages, tensorlake-native-*@0.5.144, are published.
Oct 8, 01:12:07 [email protected] is published with the latest tag.
Oct 8, 01:20 and 01:23 SafeDep and Socket flag it.
Oct 8, by 04:29 npm has removed the version, according to Tensorlake’s pull request, opened at 04:29. The revert merges at 04:32.
Oct 8, 05:22 to 05:25 The six platform packages get a 0.5.145 release. The SDK’s own 0.5.145 had not appeared at 19:26 UTC.

A clean-looking release with valid provenance

I decoded the npm provenance record for one of the six platform packages published alongside the SDK, [email protected]. It is a SLSA provenance statement that names the publish_npm.yaml workflow on main, a workflow_dispatch trigger, a GitHub-hosted runner and source commit 6386121c, the last of the 13 commits. The record for the clean 0.5.143 has the same shape and points at 52f19c8a. Apart from the commit hash and the run number, the two are alike. SafeDep puts it plainly: “The provenance is valid for a build of poisoned source.” npm’s documentation says the same in general terms: provenance “does not guarantee the package has no malicious code.”

The Verified badges on the poisoned commits settle nothing either. Nine of the 13 show as Verified because, in the words of GitHub’s documentation, GitHub “will automatically use GPG to sign commits you make using the web interface.” The four unsigned commits are all version fixes. The badge shows who signed a commit, not what the commit does, and in the keyv case the commits were unsigned.

I also hashed the two payload files from the repository at that final commit, without running them. lib/setup.mjs is 32,645 bytes and lib/Math_Symbol.js is 856,501 bytes, and both SHA-256 values match the ones Socket published for the npm package, so the commits and the package carry the same code.

Tensorlake’s pull request lists its response: admin bypass removed and direct pushes to main blocked, a second person required to approve every npm publish, release jobs that install with --ignore-scripts, and a CI check that fails if any published manifest declares an install script. It also lists work still to do by a human, including locking the compromised account and rotating the secrets available to the release workflow.

What the payload does

I did not run or decode the payload, so the details below are Socket’s and SafeDep’s.

  • Entry. The preinstall hook runs node lib/setup.mjs, an obfuscated loader that, per SafeDep, downloads Bun 1.3.13 from the official release and runs lib/Math_Symbol.js. Socket notes that “Developers do not need to import the SDK or start an agent for the hook to run.”
  • Theft. npm and GitHub tokens, AWS credentials (instance metadata, ECS, Secrets Manager and Parameter Store), a local HashiCorp Vault, Kubernetes tokens and kubeconfig files, SSH keys, .env files, crypto wallets, browser passwords, and configuration for AI development tools. Socket names Claude, Cursor, Kiro, Windsurf and Zed files, and SafeDep names ~/.claude.json and ~/.kiro/settings/mcp.json.
  • Command and control. A hard-coded domain, iseekaigogo[.]com, with fallbacks through an Ethereum contract, signed GitHub commits and dead-drop repositories. SafeDep says any response can carry code that the worm runs with eval, and that it checks in every 45 to 90 seconds.
  • Spread. With an npm token, it adds the payload and a preinstall hook to every package the token can publish, bumps the patch version and publishes. With a GitHub token, SafeDep says, it commits Claude Code and VS Code hooks as author claude and plants a “Run Copilot” workflow that dumps repository secrets.
  • The tripwire. A watcher called gh-token-monitor persists as a systemd user service, a macOS LaunchAgent or a Windows scheduled task. SafeDep says it checks the stolen GitHub token every 60 seconds for 24 hours and deletes the home directory if GitHub returns a 40x response, for example after revocation. SafeDep adds that the watcher arms only for stolen tokens whose account has no organizations. Socket’s advice makes no such distinction.

Who was actually exposed

Four details narrow the field, and a fifth keeps the real number unknown.

  • npm’s default install behavior. The hook only runs where dependency install scripts run. GitHub’s changelog for npm v12 says “npm install will no longer execute preinstall, install, or postinstall scripts from dependencies unless they are explicitly allowed in your project,” and the npm 12 configuration reference lists allow-scripts with an empty default. The registry shows npm 12.0.0 shipped on July 8, 2026, and 12.2.0 is now the latest tag, so a default install on current npm should not have run this hook. npm 11 and earlier, and projects that allowed scripts, would have run it. I did not test other package managers. Socket words it the same way: “Where dependency lifecycle scripts are permitted, this hook gives the malicious loader an execution path during installation.”
  • CI is skipped. SafeDep’s decoded loader exits when CI is true or 1, when GITHUB_ACTIONS or GITLAB_CI is true, or when RUNNER_ENVIRONMENT is github-hosted, and SafeDep infers that the payload probably did not run on Tensorlake’s own release runner. Socket lists build runners among the hosts at risk, so a runner that sets none of those variables gets no such protection.
  • The Python SDK looks untouched. The only files the poisoned commits added are the two under the repository’s typescript/lib folder, and the newest tensorlake release on PyPI was still 0.5.143 at 19:29 UTC, so the Python package does not appear to have shipped the poisoned version. The same commits did raise the Python and Rust version strings to 0.5.144.
  • A short window. The version was live from 01:12:07 UTC, and Tensorlake’s pull request says npm had removed it by 04:29, so at most about three hours and 17 minutes.
  • Unknown scale. Socket and The Register cite about 12,000 downloads a week for the package, SafeDep cites about 106,000 a month, and npm’s download API reported 18,826 for September 28 to October 4. Those figures count every version, not the poisoned one, and Socket itself says its number “does not measure downloads of the malicious version or confirmed infections.”

What to do now

  1. Search lockfiles, build logs and deployed artifacts for [email protected]. The version is gone from the registry, so also check internal mirrors, proxies and caches that may have kept a copy.
  2. Treat any host where the hook ran outside CI as compromised, and mind the order. Socket’s instruction is “Remove the token monitor before revoking any tokens.” Then revoke and replace exposed credentials and rebuild the machine from a trusted source.
  3. Audit what those credentials could reach: unexpected npm publishes, commits by an author named claude, new hook files, a “Run Copilot” workflow, and public repositories described “Shai-Hulud: Here We Go Again”.
  4. If you must use the SDK, stay on 0.5.143 until a clean 0.5.145 appears. Its provenance record points at the commit Tensorlake calls clean, and the registry’s latest tag for the SDK was still 0.5.143 at 19:26 UTC.
  5. If you maintain packages, Tensorlake’s own list is a reasonable template: no admin bypass on the default branch, a second approver on the publish environment, and --ignore-scripts in release jobs.

Indicators to search for

  • Package: [email protected]
  • SHA-256 of lib/setup.mjs: 25a0735d0db7dc40e5d45ce42d9c106067e6a66e184d967cfecfab17c3bcb5ef
  • SHA-256 of lib/Math_Symbol.js: b50a00900399ba99fb6ce1fc151519cb99d44320ef2a631f2237e1aea0ad6fec
  • Network (SafeDep): iseekaigogo[.]com, with paths /router and /hbd/
  • Persistence (SafeDep): gh-token-monitor.service, com.user.gh-token-monitor, a scheduled task named gh-token-monitor, and the folder ~/.config/gh-token-monitor/
  • Payload first line (SafeDep): globalThis.WORMTAG = 'tensrlake';

What is still unknown

  • How the account was compromised. Tensorlake calls it compromised, but neither its pull request nor Socket nor SafeDep says how.
  • How many machines ran the hook. No published count exists for the bad version.
  • Whether the six platform packages at 0.5.144 are harmful. Tensorlake’s pull request says they still need to be unpublished, and the registry still listed all six at 19:26 UTC, next to new 0.5.145 releases. I did not download them.
  • The SDK’s clean release. The Register reports that Tensorlake updated the version to 0.5.145. The registry showed 0.5.145 for the platform packages but not for the SDK itself at 19:26 UTC.
  • Who is behind it. No source I read attributes this build to a named group.
  • A fuller account. GitHub’s advisory database had no entry for the package when I queried it, and the pull request is the only first-party statement I found.

Tensorlake’s product exists to keep untrusted, model-written code away from the host. The install step of its own SDK ran outside that boundary, which is Socket’s point: “A compromised SDK creates exposure on the machine installing it, before generated code reaches a sandbox.” For detection, see our tutorials on malicious npm preinstall scripts and on npm packages that hide malware in runtime code, the route some other campaigns take to avoid install-time scanners.

Tags:

AI AgentsMalwarenpmShai-HuludSupply Chain Security

Share

Rows of identical brass-colored apartment mailboxes with small locks and name labels along an orange corridor wall
Previous Post

How to Prevent Broken Object Level Authorization (IDOR) in a FastAPI App

Yellow diamond-shaped merging traffic warning sign showing a side road joining a main road
Next Post

GitHub’s Git Rebuild Turns Repository Durability and Read Scale Into Two Separate Problems

No Comment! Be the first one.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Latest
08 Oct
How to Add Backpressure and Load Shedding to a Python Service Before Overload Takes It Down
08 Oct
GitHub’s Git Rebuild Turns Repository Durability and Read Scale Into Two Separate Problems
Trending
October 8, 2026
How to Add Backpressure and Load Shedding to a Python Service Before Overload Takes It Down
October 8, 2026
GitHub’s Git Rebuild Turns Repository Durability and Read Scale Into Two Separate Problems
October 8, 2026
A Compromised Admin Account Put the Shai-Hulud Worm Into AI Sandbox Maker Tensorlake’s npm SDK
October 8, 2026
How to Prevent Broken Object Level Authorization (IDOR) in a FastAPI App
October 8, 2026
Singapore’s AI Guidelines Turn Independent Review Into a Question of Who Sets the Risk Rating
October 8, 2026
Attackers Hijacked the .gh, .sl and .as Country Domains and Minted HTTPS Certificates for Google

Related Posts

Rows of server racks in a data center representing network infrastructure targeted by botnets
News

C0XMO Botnet Shows Why Old Router Firmware Still Matters

June 7, 2026
Close-up of a USB flash drive, representing physical data-theft risk in office security incidents
News

Fake IT Support Is Now Walking Through the Front Door

June 7, 2026
A phone security app on a smartphone resting on a laptop keyboard.
News

Everest Forms Pro Flaw Is Being Exploited to Create Rogue WordPress Admins

June 7, 2026
A phone secured by a padlock, illustrating AI data-leak containment and security controls.
News

OpenAI’s Lockdown Mode Is a Data-Leak Brake, Not a Prompt-Injection Cure

June 8, 2026
SXZ.io SXZ.io
  • [email protected]

Categories

Articles
Learning Hub
News

All Rights Reserved by SXZ.io ©2026