· via dev.to (home feed)
indexed-btree npm malware ran without install scripts and pulled C2 from Ethereum Sepolia
Checkmarx says the indexed-btree npm package hid a loader that fired when a normal library method was called, exfiltrated host data to Slack and Telegram, and fetched C2 and payloads via an Ethereum Sepolia smart contract.

What happened
Security firm Checkmarx Zero has documented a malicious npm package, indexed-btree, that was dressed up to look like the legitimate B-tree library sorted-btree and, by the firm's count, was pulling in close to two million downloads per week. The research, dated September 17, 2026, was summarized on dev.to, and BleepingComputer separately covered the campaign, highlighting how it sidesteps defenses centered on install scripts.
The package came with convincing cover: a plausible GitHub repository, a commit history, and a developer account. According to Checkmarx, the GitHub repository did not contain the malicious code that shipped inside the npm artifact, so anyone auditing the linked source rather than the published tarball would have seen clean code.
Execution without install scripts
Most npm supply-chain campaigns lean on preinstall, postinstall, or other lifecycle hooks, which many teams and registries now block or audit. indexed-btree declared none of them. Instead, Checkmarx found, the payload was tucked into an ordinary library method, BTree.prototype.set(key, value, overwrite). When that method is called with a key equal to 100 and a file named extended/sharedLoad.min.js is present, the code uses Node.js child_process.spawn() to launch the file as a detached child process.
Checkmarx describes sharedLoad.min.js as heavily obfuscated, built around encoded string arrays that rotate and verify their own integrity to resist analysis and tampering.
Exfiltration and a blockchain-based C2 channel
Once running, the loader collects host details, including operating system architecture, hostname, CPU, memory, and uptime, and sends them to hardcoded Slack channels and Telegram chats. It then polls a smart contract deployed on Ethereum Sepolia to learn its command-and-control address. Because the attacker can update the value stored in the contract at will, the C2 endpoint can be rotated without publishing a new package version, and simply blocking a domain or IP accomplishes little.
For the follow-on stage, the loader generates an X25519 key pair and reads the attacker's public key from the same contract. It derives an AES key from the ECDH shared secret, then decrypts two ciphertexts held in the contract and stitches them together into a second-stage payload. The loader also carries a cleanup routine that can delete its files and strip the trigger from the prototype method, shrinking the forensic trail left behind.
What is and is not confirmed
Two caveats matter when sizing up the incident. First, as Checkmarx itself notes, download counts are not infection counts: the malicious logic runs only when a real application calls set() with the matching key, so the number of hosts that actually executed it is unknown. Second, the contents of the second stage have not been publicly disclosed, and there is no public confirmation of execution in victim environments, actual data theft, or follow-on compromise.
What defenders can look for
On the endpoint, the clearest signal is a detached Node.js child process running sharedLoad.min.js, with 100 passed as an argument. On the network, watch for outbound traffic from Node.js workloads to Slack and Telegram APIs and to Ethereum Sepolia RPC providers, followed by connections to previously unseen destinations. Dependency inventories, lockfiles, SBOMs, and npm proxy download history will show whether indexed-btree or related packages ever entered the environment.
The countermeasures Checkmarx points to include pinning approved packages and versions, validating lockfiles, registry metadata, and tarball digests before installation, restricting egress from developer machines, CI runners, and production workloads to required services, and extending scrutiny from lifecycle scripts to the runtime behavior and child process activity of dependencies.
Why it matters
The campaign is a working demonstration that the JavaScript ecosystem's most common supply-chain control, gating install scripts, does nothing against malicious code hidden in normal library methods that every project eventually calls. Pairing that with an Ethereum smart contract as a mutable, hard-to-block C2 directory makes takedown attempts largely futile, since the infrastructure is not a server anyone can seize. And the gap between the clean GitHub repository and the poisoned npm artifact is a reminder that auditing source links is not a substitute for auditing the code that actually ships. For Node.js shops, the practical lesson is to treat dependency runtime behavior, not just installation behavior, as part of the threat surface.
- #npm
- #supply-chain
- #security
- #malware
- #node-js
- #ethereum