The trust model in the open-source ecosystem is broken. For years, developers have relied on download counts as a primary heuristic for determining the safety and legitimacy of a package. A high download count implied community adoption and, by extension, a degree of trust.
Recent intelligence reveals a surge in "download pumping" attacks on the npm registry. Threat actors are weaponizing automated infrastructure—mirrors, dependency update bots, and security scanners—to artificially inflate download metrics for malicious packages. By flooding the registry with benign versions, they trigger automated downloads, creating a veneer of legitimacy before injecting malicious code. Defenders can no longer rely on vanity metrics. We must shift our posture to verification, behavioral monitoring, and strict execution controls.
Technical Analysis
Affected Platform: Node Package Manager (npm) / Node.js ecosystem.
The Attack Chain (Download Pumping):
- Initial Setup: The attacker publishes a package and rapidly releases numerous benign versions (e.g., v1.0.0 to v1.0.50).
- Bot Triggering: These updates trigger automated systems:
- Mirrors: Public and private mirrors automatically fetch new versions.
- Dependabot/Renovate: CI/CD dependencies checking for updates trigger "GET" requests.
- Security Scanners: Auditing tools pull the package to analyze it.
- Artificial Inflation: This automated bot traffic creates a massive spike in download counts over a short period, bypassing the "low volume" warning signs often associated with new packages.
- Malicious Injection: Once the package achieves high download counts, the attacker publishes a version containing obfuscated malware (often crypto-miners, infostealers, or backdoors).
- Victim Compromise: Developers searching for libraries see the high download count, assume it is safe, and install the compromised package.
Exploitation Status: Active. This technique is currently being observed in the wild to mask typosquatted packages and deliver malicious payloads via postinstall scripts.
Detection & Response
Detecting download pumping at the registry level requires infrastructure telemetry. However, defenders can detect the outcome of these attacks—the execution of malicious payloads—on the endpoint. The most common behavior for these malicious npm packages is the execution of arbitrary shell commands (via preinstall or postinstall hooks) immediately after installation.
Sigma Rules
---
title: Potential Malicious npm Postinstall Script Execution
id: a1b2c3d4-5678-90ab-cdef-1234567890ab
status: experimental
description: Detects npm or node spawning a shell (cmd, bash, powershell), which is a common behavior for malicious packages executing postinstall scripts.
references:
- https://www.tenable.com/blog/how-cyberattackers-inflate-malicious-package-npm-download-counts
author: Security Arsenal
date: 2025/02/10
tags:
- attack.execution
- attack.t1059.001
- attack.t1059.003
- attack.t1059.004
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.cmd'
- '\npm-cli.js'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
condition: all of them
falsepositives:
- Legitimate build scripts that require shell access (verify specific package usage)
level: high
---
title: npm Spawning Network Tools on Linux
id: b2c3d4e5-6789-01ab-cdef-2345678901bc
status: experimental
description: Detects npm processes spawning curl or wget, often used by malicious packages to fetch second-stage payloads or beacon out.
references:
- https://www.tenable.com/blog/how-cyberattackers-inflate-malicious-package-npm-download-counts
author: Security Arsenal
date: 2025/02/10
tags:
- attack.command_and_control
- attack.t1071.001
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/node'
- '/npm'
ParentCommandLine|contains: 'install'
selection_child:
Image|endswith:
- '/curl'
- '/wget'
condition: all of them
falsepositives:
- Legitimate package installers fetching resources (rare, should be vetted)
level: high
KQL (Microsoft Sentinel / Defender)
// Hunt for npm processes spawning shells or network tools
DeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in ("node.exe", "npm.cmd", "node", "npm")
| where InitiatingProcessCommandLine contains "install"
| where FileName in ("powershell.exe", "cmd.exe", "pwsh.exe", "bash", "sh", "curl", "wget")
| project Timestamp, DeviceName, AccountName, InitiatingProcessCommandLine, FileName, CommandLine, FolderPath
| order by Timestamp desc
Velociraptor VQL
-- Hunt for suspicious child processes spawned by npm/node installs
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime, Parent.Pid AS ParentPid, Parent.Name AS ParentName, Parent.Commandline AS ParentCmd
FROM pslist()
WHERE Parent.Name IN ("node", "npm", "node.exe", "npm.cmd")
AND Parent.Commandline =~ "install"
AND Name IN ("bash", "sh", "powershell.exe", "cmd.exe", "curl", "wget", "powershell")
Remediation Script (Bash)
#!/bin/bash
# npm Hardening and Audit Script
# Run this on developer workstations and build agents
echo "[+] Auditing npm configuration and package integrity..."
# 1. Prevent npm from executing scripts during install (mitigates postinstall attacks)
# Note: This may break legitimate packages that rely on install scripts.
echo "[+] Checking if ignore-scripts is enabled..."
if npm config get ignore-scripts | grep -q "true"; then
echo "[+] ignore-scripts is already enabled."
else
echo "[WARNING] ignore-scripts is NOT enabled."
echo "[+] Enabling ignore-scripts globally to mitigate automated payload execution..."
npm config set ignore-scripts true
fi
# 2. Audit current package. files for unusual scripts
echo "[+] Searching for package. files in current directory..."
find . -name "package." -type f -exec sh -c '
echo "Analyzing: $1"
# Check for preinstall/postinstall scripts that call powershell, curl, or wget
if jq -e ".scripts | to_entries[] | select(.key | test("pre|post")) | select(.value | test("powershell|curl|wget|bash|cmd"))" "$1" > /dev/null 2>&1; then
echo "[ALERT] Suspicious install script detected in $1"
else
echo "[OK] No highly suspicious install scripts found in $1"
fi
' _ {} \;
echo "[+] Audit complete."
Remediation
- Verify Dependencies: Do not trust download counts. Manually verify the maintainer, repository links, and release history of every package before adding it to your environment. Look for packages with massive download spikes in a short timeframe.
- Disable Lifecycle Scripts: Configure npm to ignore
preinstall,postinstall, andprepublishscripts globally by runningnpm config set ignore-scripts true. While this may break some legitimate build tools, it is the single most effective mitigating control against supply chain malware delivered via npm. - Lock Files: Commit
package-lock.to version control. This ensures that the exact same version (integrity hash included) is installed across all environments, preventing attackers from swapping a package version in the registry without detection. - Software Composition Analysis (SCA): Implement SCA tools in your CI/CD pipeline that flag packages with suspicious versioning history or newly published packages with high download velocity.
- Private Registries: Use a private npm registry (e.g., Verdaccio, Artifactory, or AWS CodeArtifact) and firewall internet access to the public npm registry from production build servers. Curate an internal allow-list of approved packages.
Related Resources
Security Arsenal Incident Response Services AlertMonitor Platform Book a SOC Assessment incident-response Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.