Back to Intelligence

Hunting the SANDWORM_MODE: Detecting the Latest npm Supply Chain Worm

SA
Security Arsenal Team
March 2, 2026
5 min read

The software supply chain remains the most porous perimeter for modern organizations. While firewall rules and endpoint detection have matured, the dependencies we trust implicitly—open-source libraries—are increasingly being weaponized. Security researchers have recently sounded the alarm on "SANDWORM_MODE," an active campaign leveraging a cluster of at least 19 malicious npm packages. This operation is not just isolated malware; it exhibits worm-like characteristics, reminiscent of the fictional "Shai-Hulud," capable of propagating through development environments to harvest cryptocurrency keys, CI/CD secrets, and API tokens.

For a Dallas-based business or any development-forward enterprise, this threat is existential. It targets the very fuel of your infrastructure: credentials. In this post, we analyze the anatomy of this attack and provide the necessary hunting queries to secure your build pipelines.

The Threat Landscape: Why npm?

The Node Package Manager (npm) registry is the lifeblood of JavaScript and TypeScript development. However, its vast size and ease of publication make it a prime target for typosquatting and dependency confusion attacks. The SANDWORM_MODE campaign takes this a step further by embedding malicious code that executes automatically upon installation. Unlike traditional malware that requires user interaction, these packages trigger as soon as a developer runs npm install, often executing scripts in the preinstall or postinstall lifecycle hooks.

Deep Dive: Attack Vectors and TTPs

The SANDWORM_MODE campaign is sophisticated in its simplicity. The ultimate goal is credential harvesting, specifically targeting high-value assets such as crypto wallets and cloud provider keys.

TTP 1: Malicious Lifecycle Scripts

The primary delivery vector involves the abuse of npm lifecycle scripts. When a package is installed, npm runs scripts defined in package.. Attackers inject commands into postinstall that execute immediately.

TTP 2: Environment Reconnaissance

Once executed, the malware performs reconnaissance. It scans the filesystem for specific patterns:

  • Crypto Keys: Looking for files like wallet., keystore, or scanning browser extension data.
  • CI/CD Secrets: Targeting .git/config, .env files, and known CI tool directories (e.g., .github, .circleci).
  • Configuration Files: Scanning for .npmrc, .aws/credentials, and kubeconfig files.

TTP 3: Exfiltration via DNS/HTTP

The harvested data is typically Base64 encoded and exfiltrated via hardcoded Command and Control (C2) endpoints. The "worm" aspect suggests that if the environment has write access to other project repositories, the malware may attempt to propagate its own dependencies, infecting other projects downstream.

Detection and Threat Hunting

To catch this in your environment, you cannot rely solely on signature-based antivirus. You must hunt for behaviors. Below are detection mechanisms ranging from Endpoint telemetry to EDR queries.

1. KQL for Microsoft Sentinel / Defender 365

This query looks for Node.js processes (node or npm) initiating network connections to unknown external endpoints immediately following a package installation event. It also flags attempts to access sensitive file paths.

Script / Code
let SuspiciousFiles = dynamic([".env", "wallet", "keystore", "id_rsa", ".npmrc", "credentials"]);
DeviceProcessEvents
| where Timestamp > ago(7d)
// Filter for npm or node execution
| where InitiatingProcessFileName in ("npm.exe", "node.exe", "npm", "node")
| where ProcessCommandLine has_any ("install", "i ")
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessId
| join kind=inner (
    DeviceFileEvents
    | where Timestamp > ago(7d)
    | where FileName has_any (SuspiciousFiles) orFolderPath contains ".aws"
    | where InitiatingProcessFileName in ("node.exe", "npm", "node")
) on InitiatingProcessId
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, FileName, FolderPath
| summarize count() by Timestamp, DeviceName, AccountName, FileName
| order by Timestamp desc

2. PowerShell: Local Environment Audit

Run this script on developer workstations or build servers to check for recently modified npm packages that have suspicious postinstall scripts pointing to external obfuscated URLs.

Script / Code
# Scan node_modules for suspicious postinstall scripts
$basePath = ".\node_modules"
if (Test-Path $basePath) {
    Get-ChildItem -Path $basePath -Recurse -Filter "package." | ForEach-Object {
        $pkg = $_ | Get-Content | ConvertFrom-Json
        if ($pkg.scripts.postinstall) {
            # Check for obfuscated JS or external network calls
            if ($pkg.scripts.postinstall -match "curl|wget|http|eval|require\(.*http" ) {
                Write-Host "[!] Suspicious postinstall found in: $($_.FullName)"
                Write-Host "    Script: $($pkg.scripts.postinstall)"
            }
        }
    }
}
else {
    Write-Host "No node_modules found in current directory."
}

3. Bash: Linux/macOS Build Agent Check

This snippet checks for running Node processes that are holding open network connections to non-standard ports, a common sign of active C2 beaconing.

Script / Code
#!/bin/bash
# Find node processes with active network connections
lsof -i -a -c node
# Alternatively, check for recent modifications to package-lock.
# which might indicate a dependency confusion attack
find . -name "package-lock." -mtime -1 -exec ls -la {} \;

Mitigation Strategies

Detecting SANDWORM_MODE is only half the battle; preventing it requires strict supply chain hygiene.

  1. Pin Your Dependencies: Avoid using semantic versioning ranges like ^1.0.0 in production builds. Use exact versions (e.g., 1.0.0) to lock in the code you have vetted.
  2. Implement Lockfile Auditing: Never commit package. without package-lock.. Before every build, run npm ci (clean install) rather than npm install to ensure consistency.
  3. Automate SBOM Generation: Maintain a Software Bill of Materials (SBOM) for every application. You cannot protect what you do not know you have.
  4. Restrict Scripts: Use the --ignore-scripts flag during installation if you do not require build steps for production dependencies, or use a tool that allows policy enforcement on script execution.

Related Resources

Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub

socmdrmanaged-socdetectionsupply-chainnpmthreat-huntingmalware

Is your security operations ready?

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