Skip to content

Security1 publisher2 min readPublished

Malicious npm package indexed-btree fires its loader from a runtime library call

Checkmarx says a fake sorted-btree clone reached 2 million weekly downloads with clean install scripts, starting its loader only when an application calls BTree.prototype.set with a particular key. Nine related packages have been pulled.

The Watch · Security desk

Illustration accompanying Malicious npm package indexed-btree fires its loader from a runtime library call

What happened

  • Checkmarx found indexed-btree, an npm package impersonating the legitimate sorted-btree library, which had reached 2 million weekly downloads by the time it was flagged.
  • The package has no installation scripts, so the install looks clean and none of npm v12's approval mechanisms fire at any point during it.
  • GitHub's June 2026 npm measures block preinstall, install and postinstall scripts unless approved, and stop npm pulling dependencies from Git repositories or remote URLs without permission.
  • Once running, the malware profiles the host and exfiltrates over hardcoded Slack and Telegram channels, then polls an Ethereum smart contract on the Sepolia test network for its second stage.

Compiled by The WatchSomething wrong?How this is made

Why it matters

  • constraint Detection for this package class has to come from something watching the application while it runs; install-time gating is the wrong place to look for it.
  • cost Anyone who pulled one of the ten packages pays for remediation in rotated secrets and development environments restored from backup.
  • capability Reviewing the installed package after an alert is no longer a dependable check, because the operators can strip the trigger out of the code on command.
  • contradiction Checkmarx's recommended fix is runtime behavioral analysis, yet the loader it describes fires only on a specific key value. That single trigger bounds what a sandbox run will ever observe.

BTree.prototype.set() is the write path of a sorted-map library, so an application that uses indexed-btree calls it repeatedly. Checkmarx says the loader sits inside that method and fires when the caller passes a specific key value [6]. "The malware loader hides inside the library's own BTree.prototype.set method, which is the main function that every user would call constantly," Checkmarx said [8]. The firm called the approach "a well-built way to sneak past standard taint-analysis tools and most static scanners" [9].

GitHub built the June 2026 npm controls after repeated supply-chain attacks on open-source ecosystems since late 2025 [22]. They work against install-script malware, and indexed-btree does not need an install script, so npm v12's approval flow has nothing to approve [6][7].

Checkmarx advises developers to stop relying on install-time scanning alone and to add runtime behavioral analysis [17]. That buys partial coverage: the loader waits on a specific key value, so a sandbox that imports the package and exercises it will watch ordinary btree operations unless the key it writes happens to match [6].

indexed-btree stood at 2 million weekly downloads when Checkmarx flagged it [2]. The nine related packages Checkmarx had removed from npm [14] add up to 5,375,635 downloads between them, with btree-core accounting for 1,951,274 of that [15][19]. BleepingComputer did not say what period its figures for the nine cover [21]. Six of the ten package names contain the string btree [23]. A dependency-tree search on that string covers most of the set.

Checkmarx says the operators built a legitimate-looking GitHub repository, populated its commit history and curated the developer account [13]. The firm also ties a wallet holding 109 ETH to the operation, without attributing those funds to cryptocurrency theft in the report [3].

What to watch

  • Whether Checkmarx or GitHub publishes the trigger key values. With them, teams could check their own call sites instead of guessing.
  • Whether npm adds an enforced runtime or publish-time behavioral signal, or leaves the lifecycle-script approval gate as the only control.
  • Whether the same operator returns with new packages seeded through another curated GitHub account and commit history.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories