It Started With a Routine npm Install
You run npm install a dozen times a day. It’s muscle memory—part of the background hum of being a JavaScript developer. You don’t stop to wonder what actually executes on your machine every time you add a dependency.

On July 11, 2026, someone who installed jscrambler version 8.14.0 got a lot more than they paid for. The package, a build-time tool for JavaScript code protection by the Portuguese security company Jscrambler, was compromised—and simply running npm install was enough to deploy a full Rust infostealer onto the victim’s machine.
Socket Security flagged the release six minutes after it hit npm. But in that window, and in the hours that followed through four more malicious releases, the damage was done.
What Actually Happened
The attacker compromised an npm publishing credential belonging to the Jscrambler maintainer account. They didn’t push through a pull request, a commit, or any of the normal code review pipeline. Version 8.14.0 simply appeared on npm with two brand-new files that had never been in the project’s public source repository: dist/setup.js and dist/intro.js.
Despite the .js extension, intro.js is not JavaScript. It’s a roughly 7.8MB custom binary container packing three gzip-compressed native executables—one each for Linux x86-64, Windows x86-64, and macOS ARM64.
During installation, setup.js picks the binary matching the host operating system, writes it to the system temp directory under a random hidden name, marks it executable, and launches it in the background with its output completely hidden. No console popup. No permission prompt. Just a native binary running silently on your machine with whatever access your install process had.
And this wasn’t a one-and-done. The attacker pushed five malicious versions over about three hours: 8.14.0, 8.16.0, 8.17.0, 8.18.0, and 8.20.0. Starting with 8.18.0, when it became clear that the preinstall hook was being detected, the attacker moved the dropper into the package’s main code and CLI entry points. That meant npm install --ignore-scripts—the standard workaround for suspicious packages—no longer stopped it.
Version 8.22.0 is the clean release. Jscrambler has deprecated the malicious versions, but they’re still on npm and installable by exact version pinning.
The Payload: A Developer’s Worst Nightmare
The Rust-built infostealer has one of the broadest target lists I’ve seen in a supply chain attack. It’s clearly designed for developer workstations and CI build environments—because that’s exactly where jscrambler users would be running it.
Cloud credentials. AWS, Azure, and Google Cloud—including the metadata endpoints that CI runners use. If your build system had access to any cloud provider, the attacker now has those credentials too.
Cryptocurrency wallets. MetaMask, Trust Wallet, Coinbase Wallet, Phantom, and Exodus. The malware doesn’t just copy files—it attempts to decrypt wallet vaults using the scrypt key derivation parameters it extracts.
Password managers. Bitwarden vaults. The entire password database.
Browser-stored data. Saved passwords, cookies, and session tokens from every major browser.
Messaging and collaboration sessions. Discord, Slack, Telegram, and Steam sessions—meaning an attacker could authenticate as the victim in these services without needing their password.
AI coding tool configs. This one stood out to me. The malware targets configuration files for Claude Desktop, Cursor, Windsurf, VS Code, and Zed—specifically looking for API keys and Model Context Protocol (MCP) server credentials that developers store in these tools. AI coding tools are now first-class surveillance targets in supply chain malware.
On Linux, the payload goes further. It links the kernel’s BPF library and can load an eBPF program directly into the kernel from memory. That’s kernel-level persistence—not the kind of thing you catch with a simple file scan. On Windows and macOS, it sets up persistence mechanisms: a hidden scheduled task on Windows that relaunches every minute, and a macOS LaunchAgent that reloads on login.
The stolen data gets shipped over TLS to hard-coded command-and-control servers, with Tor infrastructure as a fallback network route.
The Ironic Timing
Here’s where it gets almost absurd. Three days before this attack, npm 12 shipped on July 8 with a critical security change: dependency install scripts are disabled by default. No more automatic execution of preinstall and postinstall hooks without explicit approval.
If every developer and CI system in the world had already migrated to npm 12, the jscrambler preinstall hook would never have fired. The attack would have been blocked by default.
But most of us haven’t migrated. I checked my own projects, and several were still running npm 10 or 11. The npm 12 migration guide I wrote for this blog just a few days ago is suddenly a lot more urgent.
It’s a pattern I’ve seen before in security: the fix exists, the knowledge is public, but the adoption lag creates a window the attackers exploit anyway.
What This Means for Developers and Teams
As someone who manages ICT operations and runs development teams, this attack hits close to home. The jscrambler compromise isn’t an outlier—it’s the new baseline for npm security incidents.
Look at the last 12 months: the Shai-Hulud worm that spread through install hooks last September. The chalk and debug package takeover through a phished maintainer account. The Axios compromise in March that pushed a cross-platform trojan to 83 million weekly downloads. These aren’t isolated events—they’re a pattern of attackers realizing that open source package registries are the ultimate force multiplier.
What makes the jscrambler case particularly concerning is the sophistication of the evasion. The attacker didn’t just drop a preinstall hook and hope for the best. When the preinstall vector was detected, they moved the payload into the main code path. They deployed a Rust binary with ChaCha20-Poly1305 string encryption (roughly 2,400 encrypted strings recovered by Socket). They built cross-platform capability with eBPF kernel access on Linux.
This is not a script kiddie operation. This is a threat actor with resources, patience, and an understanding of the developer ecosystem.
What You Should Do Right Now
If you or your team have ever used jscrambler, here’s the checklist:
- Check your lockfiles. Search
package-lock.json,yarn.lock, andpnpm-lock.yamlfor[email protected],8.16.0,8.17.0,8.18.0, or8.20.0. Also check CI logs for any execution ofdist/setup.jsfrom July 11 onward. - Upgrade to 8.22.0 or pin to 8.13.0 (the last clean release before the incident). Clear your npm cache afterward.
- Rotate everything. If the package ran on any machine, treat every credential it could reach as compromised. Cloud API keys, npm tokens, GitHub tokens, AI tool API keys, MCP server credentials—all of them. Revoke Discord, Slack, and browser sessions too.
- Check for persistence. On Windows, inspect Task Scheduler for hidden tasks that launch every minute. On macOS, check
~/Library/LaunchAgentsfor unfamiliar plist files. On Linux, look for unexpected eBPF programs loaded into the kernel. - Migrate to npm 12. The install-scripts-off-by-default change is a genuine security improvement. Run your build pipeline through
npm 12 installand use the newapprove-scriptsworkflow for the packages you actually trust.
The Bigger Picture
Every supply chain attack follows the same logic: compromise one account, infect thousands of downstream users. The economics are brutally simple. One compromised npm credential gives an attacker access to every CI pipeline and every developer workstation that runs the infected package.
We’re past the point where individual vigilance is enough. The defense has to be structural: package managers with install scripts off by default, the economics of self-hosting open source models to reduce external dependency risk, runtime detection tools in CI pipelines, credential rotation policies, and a culture where “it’s just an npm install” is no longer taken for granted.
For my part, I’m auditing every dependency I manage—not just the direct ones, but the transitive ones too. And I’m migrating every project I own to npm 12 this week. Not next month. This week.
The jscrambler attacker was caught within hours, but the stolen secrets are already out there. The question isn’t whether there will be a next time. It’s whether we’ll be ready when it comes.