Back to Intelligence

Shai-Hulud Worm Compromises tensorlake npm SDK (v0.5.144) — Detection and Remediation Guide for Credential-Theft Supply Chain Attacks

SA
Security Arsenal Team
October 8, 2026
11 min read

Security researchers at Socket have confirmed that version 0.5.144 of the tensorlake npm package — a TypeScript SDK for Tensorlake applications, sandboxes, and cloud services — was compromised as part of the ongoing ChainDrop / Shai-Hulud supply chain campaign. The malicious release contains obfuscated code that harvests credentials, exfiltrates secrets, establishes persistence, and executes remotely supplied code.

This is not a theoretical risk. Shai-Hulud is a self-propagating worm — its hallmark behavior is stealing npm publishing tokens and cloud credentials from infected developer machines and CI/CD runners, then using those tokens to automatically publish compromised versions of other packages the victim maintains. Every developer workstation or pipeline that installed tensorlake@0.5.144 is a potential pivot point that can poison downstream packages and leak cloud infrastructure credentials.

If your organization uses npm anywhere in its build pipeline — and it almost certainly does — treat this as an active incident-response scenario, not a patching exercise. Credential rotation is mandatory, not optional.

Technical Analysis

What Is Affected

  • Package: tensorlake on the npm registry
  • Malicious version: 0.5.144
  • Package type: TypeScript SDK for Tensorlake applications, sandboxes, and cloud services
  • Attack campaign: ChainDrop / Shai-Hulud supply chain operation
  • No CVE identifier has been assigned to this compromise as of publication; it is tracked by campaign name (Shai-Hulud) and malicious package version.

How the Attack Works

Based on Socket's analysis and the established Shai-Hulud tradecraft, the malicious version executes during or immediately after package installation — typically via npm lifecycle scripts (preinstall/postinstall) embedded in the package, which is the standard execution vector for npm supply chain malware. The observed behavior chain:

  1. Obfuscated payload execution. Malicious JavaScript is heavily obfuscated to evade static scanners and casual code review. It detonates when the package is installed or imported, running with the full privileges of the installing user or CI service account.
  2. Credential harvesting. The payload scans the host for high-value secrets: ~/.npmrc (npm auth tokens), ~/.aws/credentials, ~/.azure/, ~/.config/gcloud/, SSH keys (~/.ssh/), git credentials, .env files, and environment variables injected into CI runners (e.g., NPM_TOKEN, AWS_ACCESS_KEY_ID, GITHUB_TOKEN, AZURE_*, KUBE_CONFIG).
  3. Secret exfiltration. Harvested material is staged and sent to attacker-controlled infrastructure — historically over HTTPS to disposable domains, webhook services, or hard-coded endpoints, blending into normal developer egress traffic.
  4. Persistence. The malware drops mechanisms to survive package removal — modifying shell profiles (~/.bashrc, ~/.zshrc), dropping files into startup locations, or planting persistent jobs in CI configuration.
  5. Remote code execution. The implant beacons out and accepts remotely supplied code, giving operators an interactive foothold on developer workstations and build agents.
  6. Worm propagation (Shai-Hulud's defining trait). Using stolen npm tokens, the malware authenticates to the npm registry, enumerates packages the victim maintains, and publishes trojanized versions — exponentially expanding the blast radius with each infection.

Exploitation Status

This is confirmed, active, in-the-wild exploitation. The malicious version was live on the npm registry and downloadable by anyone running npm install tensorlake during the exposure window. The self-propagating nature of Shai-Hulud means exposure compounds over time: one compromised maintainer account seeds dozens of downstream packages.

Why CI/CD Pipelines Are the Real Target

Developer laptops are valuable, but CI/CD runners are the jackpot. Build agents routinely hold:

  • Scoped-down-but-powerful cloud IAM credentials (often with artifact-push and deploy rights)
  • npm/GitHub publishing tokens with write access to dozens of packages
  • Signing keys and registry credentials
  • Ephemeral environment variables containing production secrets

A single poisoned npm install in a build job can silently exfiltrate everything the pipeline touches — and because builds run constantly, detection windows are measured in minutes of exposure multiplied by hundreds of executions.

Detection & Response

Step 1: Determine Exposure

Immediately inventory every package lockfile, build artifact, and npm cache in the organization for tensorlake@0.5.144. Check package-lock.json, yarn.lock, pnpm-lock.yaml, npm audit logs, artifact repositories (Artifactory/Nexus/GitHub Packages), and CI/CD build logs for the exact version string.

Sigma Rules

The following rules target the observable behaviors of npm supply chain malware: lifecycle script execution spawning shells/credential-access tooling, node processes reading credential stores, and suspicious child processes of the npm ecosystem.

YAML
---
title: NPM Lifecycle Script Spawning Suspicious Child Process
id: 3f8a2c41-9b7e-4d12-a6f5-8c1e4b2d9f07
status: experimental
description: Detects npm/node install processes spawning shells or script interpreters, consistent with malicious preinstall/postinstall lifecycle scripts in compromised packages such as tensorlake 0.5.144 (Shai-Hulud campaign).
references:
  - https://thehackernews.com/2026/10/tensorlake-npm-package-compromised-to.html
  - https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/10/21
tags:
  - attack.initial_access
  - attack.t1195.002
  - attack.execution
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\node.exe'
      - '\npm.cmd'
      - '\npm.exe'
      - '\npx.cmd'
      - '\yarn.cmd'
      - '\pnpm.exe'
  selection_child:
    Image|endswith:
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\cmd.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
      - '\curl.exe'
      - '\certutil.exe'
      - '\bitsadmin.exe'
  condition: selection_parent and selection_child
falsepositives:
  - Legitimate native module compilation (node-gyp) may spawn cmd.exe
  - Build tooling wrappers invoking PowerShell during installs
level: high
---
title: Node Process Accessing Credential and Secret Stores
id: 9d4b7e02-3c18-4f65-b8a1-2e6d5c9a4f38
status: experimental
description: Detects node/npm processes reading credential files (.npmrc, cloud provider credentials, SSH keys), consistent with Shai-Hulud credential harvesting behavior observed in the tensorlake 0.5.144 compromise.
references:
  - https://thehackernews.com/2026/10/tensorlake-npm-package-compromised-to.html
  - https://attack.mitre.org/techniques/T1552/001/
author: Security Arsenal
date: 2026/10/21
tags:
  - attack.credential_access
  - attack.t1552.001
  - attack.t1552.004
logsource:
  category: file_event
  product: windows
detection:
  selection_image:
    Image|endswith:
      - '\node.exe'
      - '\npm.cmd'
      - '\npm.exe'
      - '\npx.cmd'
  selection_target:
    TargetFilename|contains:
      - '\.npmrc'
      - '\.aws\credentials'
      - '\.azure\'
      - '\.config\gcloud\'
      - '\.ssh\id_'
      - '\.git-credentials'
      - '\.env'
  condition: selection_image and selection_target
falsepositives:
  - npm CLI legitimately reads .npmrc during authenticated installs/publishes; tune by build-agent context
  - Developer tooling extensions reading .env files in editor contexts
level: medium
---
title: Persistence via Shell Profile or Startup Modification by Node Process
id: 5c1f8d63-7a29-4b84-e6d2-1f3a9c7b5e04
status: experimental
description: Detects node/npm child processes modifying shell profiles or startup locations, matching the persistence behavior attributed to the Shai-Hulud worm in the tensorlake supply chain compromise.
references:
  - https://thehackernews.com/2026/10/tensorlake-npm-package-compromised-to.html
  - https://attack.mitre.org/techniques/T1546/004/
author: Security Arsenal
date: 2026/10/21
tags:
  - attack.persistence
  - attack.t1546.004
  - attack.t1547.001
logsource:
  category: file_event
  product: linux
detection:
  selection_image:
    Image|endswith:
      - '/node'
      - '/npm'
      - '/npx'
  selection_target:
    TargetFilename|endswith:
      - '/.bashrc'
      - '/.zshrc'
      - '/.profile'
      - '/.bash_profile'
  condition: selection_image and selection_target
falsepositives:
  - Developer environment setup scripts (rare outside initial provisioning)
level: high

KQL Hunt — Microsoft Sentinel / Defender

This query hunts for node/npm processes touching credential stores or spawning suspicious children across both Windows (Defender) and Linux (Syslog-ingested) estates. Run it over at least the last 30 days; extend to cover the full window in which 0.5.144 was available if your build logs indicate earlier exposure.

KQL — Microsoft Sentinel / Defender
// Hunt: npm/node processes accessing credential stores or spawning shells
// Context: tensorlake 0.5.144 / Shai-Hulud supply chain compromise
let lookback = 30d;
let credPaths = dynamic([".npmrc", ".aws/credentials", ".azure", "gcloud", ".ssh/id_", ".git-credentials", ".env"]);
let suspiciousChildren = dynamic(["powershell.exe", "pwsh", "cmd.exe", "bash", "sh", "curl", "wget", "mshta.exe", "certutil.exe"]);
union isfuzzy=true
(
  DeviceProcessEvents
  | where Timestamp > ago(lookback)
  | where InitiatingProcessFileName in~ ("node.exe", "node", "npm", "npm.cmd", "npx", "yarn", "pnpm")
  | where FileName in~ (suspiciousChildren)
     or ProcessCommandLine has_any (credPaths)
  | project Timestamp, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, InitiatingProcessCommandLine, AccountName, ReportId
),
(
  DeviceFileEvents
  | where Timestamp > ago(lookback)
  | where InitiatingProcessFileName in~ ("node.exe", "node", "npm", "npm.cmd", "npx")
  | where FileName has_any (credPaths) or FolderPath has_any (credPaths)
  | project Timestamp, DeviceName, InitiatingProcessFileName, FolderPath, FileName, ActionType, AccountName, ReportId
),
(
  Syslog
  | where TimeGenerated > ago(lookback)
  | where ProcessName has_any ("node", "npm", "npx")
  | where SyslogMessage has_any (credPaths) or SyslogMessage has_any ("curl", "wget", "/bin/sh", "/bin/bash")
  | project TimeGenerated, Computer, ProcessName, SyslogMessage, HostIP
)
| order by Timestamp desc

Velociraptor VQL — Endpoint Forensics

Deploy this artifact against developer workstations and build agents to surface live Shai-Hulud-style activity: node processes with suspicious command lines, outbound network connections from node, and shell-profile persistence artifacts.

VQL — Velociraptor
-- Hunt: npm supply chain compromise indicators (Shai-Hulud / tensorlake 0.5.144)
-- Surfaces node processes touching credentials, suspicious child spawns, and outbound connections

-- Part 1: Suspicious node/npm process execution
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE (Name =~ '(?i)node|npm|npx|yarn|pnpm')
  AND (CommandLine =~ '(?i)\.npmrc|\.aws|credentials|id_rsa|\.env|gcloud|azure'
       OR CommandLine =~ '(?i)curl|wget|powershell|/bin/sh|/bin/bash|bash -c|sh -c')

-- Part 2: Outbound network connections from node processes (exfil/beaconing)
SELECT Pid, Name, CommandLine, Status, "Laddr.IP" AS LocalIP, "Laddr.Port" AS LocalPort,
       "Raddr.IP" AS RemoteIP, "Raddr.Port" AS RemotePort
FROM netstat()
WHERE Name =~ '(?i)node'
  AND Status =~ 'ESTABLISHED'
  AND RemotePort IN (80, 443, 8080, 8443)

-- Part 3: Recently modified shell profiles (persistence check, Linux/macOS endpoints)
SELECT FullPath, Size, Mtime, Atime
FROM glob(globs=[
    '/home/*/.bashrc',
    '/home/*/.zshrc',
    '/home/*/.profile',
    '/root/.bashrc'
])
WHERE Mtime > now() - 2592000  -- modified within last 30 days
ORDER BY Mtime DESC

Remediation and Verification Script

Use this Bash script on developer workstations and Linux build agents to check for installation of the malicious version, inspect persistence locations, and identify node processes holding outbound connections. Review output before taking destructive action.

Bash / Shell
#!/bin/bash
# tensorlake 0.5.144 / Shai-Hulud exposure check — run on dev machines and CI agents
echo "=== [1] Searching for malicious tensorlake version in lockfiles ==="
grep -rl "tensorlake" ~ --include="package-lock.json" --include="yarn.lock" --include="pnpm-lock.yaml" 2>/dev/null | while read -r f; do
  grep -H "0.5.144" "$f" && echo ">>> COMPROMISED VERSION FOUND: $f"
done

echo "=== [2] Checking npm cache for tensorlake 0.5.144 ==="
npm cache ls tensorlake 2>/dev/null | grep "0.5.144" && echo ">>> Malicious version present in npm cache — purge with: npm cache clean --force"

echo "=== [3] Globally installed tensorlake? ==="
npm ls -g tensorlake 2>/dev/null

echo "=== [4] Recently modified shell profiles (persistence) ==="
find ~ -maxdepth 1 \( -name ".bashrc" -o -name ".zshrc" -o -name ".profile" -o -name ".bash_profile" \) -mtime -30 -exec ls -la {} \;

echo "=== [5] Suspicious entries in shell profiles ==="
grep -nE "curl|wget|base64|node -e|eval" ~/.bashrc ~/.zshrc ~/.profile ~/.bash_profile 2>/dev/null

echo "=== [6] Node processes with established outbound connections ==="
ss -tnp 2>/dev/null | grep -E "node|npm" | grep ESTAB

echo "=== [7] node_modules copies of tensorlake on disk ==="
find ~ /opt /srv /var/lib -type d -name "tensorlake" -path "*node_modules*" 2>/dev/null | head -20

echo "=== DONE. Any hit in sections 1-2 requires credential rotation (see remediation steps). ==="

Remediation

If any system installed tensorlake@0.5.144, assume full compromise of every secret that system could access. Execute in this order:

  1. Pin and purge immediately. Remove tensorlake@0.5.144 from all lockfiles. Roll back to the last known-good version published before the compromise, or remove the dependency entirely until Tensorlake publishes a clean release and confirms registry integrity. Verify the maintainer's advisory on the npm package page and the Socket research blog for the confirmed clean version before reinstalling — do not blindly npm update.
  2. Rotate every credential the host could reach. This is non-negotiable and includes: npm access tokens (npm token revoke plus registry-side revocation), GitHub/GitLab tokens and SSH keys, AWS/Azure/GCP credentials, any .env-stored secrets, CI/CD service account credentials, and kubeconfig files. Prioritize tokens with publish rights — those are what Shai-Hulud uses to propagate.
  3. Audit npm and GitHub account activity. Review npm package publish logs for every maintainer whose token may have been exposed. Look for version bumps you did not authorize — that is the worm's signature. GitHub: audit org audit logs for new tokens, deploy keys, and OAuth grants created during the exposure window.
  4. Rebuild from clean sources. CI artifacts built while the malicious package was present cannot be trusted. Invalidate build caches, purge npm caches (npm cache clean --force), and rebuild artifacts from a known-good lockfile.
  5. Quarantine and reimage where warranted. If credential-harvesting behavior is confirmed on a developer workstation or persistent build agent, reimage it. The persistence and RCE components mean simple package removal is not sufficient cleanup.
  6. Harden the pipeline against the next one — because there will be a next one:
    • Enforce npm ci with lockfile integrity in CI instead of npm install.
    • Disable lifecycle scripts where feasible: npm config set ignore-scripts true for CI environments, with explicit allowlists for packages that legitimately need build scripts.
    • Scope npm tokens to the minimum packages and permissions; use granular, expiring tokens instead of legacy publish tokens.
    • Gate new dependency versions behind a delay window (e.g., 72 hours) and automated malware scanning (Socket, npm audit, or equivalent) before promotion to builds.
    • Run builds in ephemeral, network-egress-restricted runners so a compromised install cannot reach arbitrary exfiltration endpoints or persist beyond one job.
  7. Monitor for downstream poisoned packages. Because Shai-Hulud self-propagates, subscribe to Socket/GitHub advisories and monitor your full dependency tree — not just direct dependencies — for new Shai-Hulud-linked releases in the coming weeks.

There is no vendor patch to apply here; the fix is version rollback, credential rotation, and pipeline hardening. Speed matters more than completeness on the rotation step — every hour a stolen npm publish token remains valid is an hour the worm can keep spreading under your name.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.