A malicious npm package posing as a routine B-tree indexing utility has been caught running its entire attack chain from inside ordinary application code, not the install scripts that most npm malware still relies on. The package — "indexed-btree" — has been traced back to a single publisher account, since removed, that racked up millions of downloads in a matter of weeks before the package and its GitHub repository were pulled.
What happened
"indexed-btree" mimicked a legitimate sorted B-tree library closely enough to pass a casual glance. Instead of hiding malicious behavior in a preinstall or postinstall script — the classic install-time trick — the payload was buried inside a normal-looking method, BTree.prototype.set(). Calling that method loaded a secondary file that unpacked an obfuscated first-stage loader.
From there, the malware fingerprinted the host, beaconed details to a hard-coded Slack channel and Telegram bot, and pulled encrypted next-stage payload chunks from a smart contract deployed on the Sepolia testnet — a technique known as EtherHiding that uses blockchain storage to dodge takedowns. The stages were merged client-side to assemble the final payload, and the package then deleted its own malicious artifacts to erase the trigger.
Researchers identified at least ten related packages tied to the same publishing operation, all since pulled from the registry: ordered-kv-index, btree-leaderboard, priority-slot-queue, btree-range-store, btree-core, btree-time-index, btree-lru-cache, neighbor-key-map, sliding-score-window, and mutes-forge.
Why it matters
This campaign lines up with a broader shift in the npm ecosystem. Recent registry changes block automatic execution of install-time scripts by default — closing off one of the easiest ways malware has historically ridden along with an npm install. indexed-btree shows that attackers don't need that hook at all: if the malicious code just looks like ordinary library logic, it runs the moment a legitimate function gets called.
The pattern isn't isolated. A related campaign spanning npm and other package registries has been compromising maintainer accounts and inserting obfuscated payloads directly into source files — including alternate language entry points — rather than relying on any single fixed delivery mechanism. Across both campaigns, the throughline is the same: registry-level defenses raise the cost of the easy attack, and operators respond by adapting rather than disappearing.
What to do
- Audit before you upgrade, not after. Pin dependency versions and review diffs on version bumps for packages with sudden download spikes or very recent publish dates — both were red flags here.
- Don't rely on install-script blocking alone. It closes one door; runtime behavior monitoring and outbound network inspection during CI/build are needed to catch payloads triggered by normal function calls.
- Watch for unusual outbound traffic, especially beacons to messaging platforms (Slack, Telegram) or unexpected blockchain RPC calls from build or application processes — both are increasingly used to host and relay malware stages precisely because they're hard to take down.
- Treat maintainer-account takeovers as a supply-chain risk, not just an account-security issue — compromised publishing accounts are now a primary delivery path for this class of attack.
Layered detection — before install, during execution, and after deployment — is the only approach that keeps pace with attackers who are actively re-routing around each new control.
