An aggressive and technically-sophisticated supply chain attack has hit the JavaScript community following the recent npm phishing campaign, leveraging stolen credentials to compromise some of the ecosystem’s most widely used packages.
The campaign began with targeted phishing emails spoofing npm’s support address, using typosquatted domains such as npnjs[.]com
to trick developers particularly those maintaining high-traffic packages into divulging credentials.
These phishing messages bypassed email protections in some cases due to missing DMARC and SPF records on npmjs.org
, further increasing the risk that maintainers would be fooled.
Compromise of ‘is’ Package
Within days of the initial wave, attackers exploited stolen tokens to publish rogue updates to several npm packages, most notably the ‘is’ package, which receives approximately 2.8 million downloads per week.
Other library victims include eslint-config-prettier
, eslint-plugin-prettier
, synckit
, @pkgr/core
, napi-postinstall
, and got-fetch
.
The malicious updates were automatically distributed through the npm registry, making infection almost instant for downstream projects and CI systems that use automated dependency updates. The attack on the ‘is’ package stands out due to its cross-platform approach.
While the attackers also delivered Scavenger malware in the form of a Windows-specific malicious DLL embedded in eslint-config-prettier
, the malicious versions of ‘is’ (notably 3.3.1 and 5.0.0) contain a JavaScript loader capable of running on any major operating system.
This loader, heavily obfuscated, reconstructs its payload in memory and immediately executes it via the new Function
construct.
Key system information such as the hostname, OS and CPU type, working directory, and all environment variables are captured and then exfiltrated to a remote WebSocket-based command and control server.
Critically, the loader enables the threat actor to send and execute arbitrary JavaScript on infected hosts in real time, turning every compromised server or developer workstation into a remote shell.
Impact on the Developer Ecosystem
In this campaign, attackers hijacked maintainer accounts through phishing, then used their access to remove legitimate owners and publish malware-laden versions directly to npm.
In the case of is
, the malicious changes persisted due to a breakdown in npm’s owner verification notifications, with maintainers publicly reporting the incident days after release.
Other key packages such as got-fetch
were compromised through similar social engineering, further increasing the attack’s blast radius.
Reverse engineering efforts, including a widely-circulated report from the Humpty’s RE Blog, have traced the Windows-targeted payload (Scavenger) to aggressive information stealing behavior: scraping Chrome extensions, cached session data, .npmrc
files, SSH keys, and even browser credentials before exfiltrating them over encrypted channels.
According to the report, The JavaScript-only approach in the ‘is’ package extends these capabilities across all platforms, with the added danger that every message received from its C2 acts as immediate remote code.
Fallout from the compromise is still unfolding. Developers report disabling of browser security settings, potential credential leakage, and, in some cases, resorting to full drive wipes and operating system reinstallations to guarantee clean systems.
Simply rolling back affected npm packages is insufficient if credentials or sensitive files have already been exfiltrated or if malware has achieved persistence by overwriting package files in local installs.
Security experts strongly advise developers to reset all authentication credentials, rotate secrets, inspect workstations for IOCs, and audit the dependency graph with advanced tools capable of detecting behavioral anomalies within npm packages.
Dedicated solutions such as Socket’s Safe npm CLI and real-time scanning GitHub Apps are now being used to block and alert on infected packages and updates.
Indicators of Compromise (IOCs)
Package Name | Malicious Versions |
---|---|
eslint-config-prettier | 8.10.1, 9.1.1, 10.1.6, 10.1.7 |
eslint-plugin-prettier | 4.2.2, 4.2.3 |
synckit | 0.11.9 |
@pkgr/core | 0.2.8 |
napi-postinstall | 0.3.1 |
got-fetch | 5.1.11, 5.1.12 |
is | 3.3.1, 5.0.0 |
Find this Story Interesting! Follow us on LinkedIn and X to Get More Instant Updates