indexed-btree npm Campaign: Runtime-Triggered Loader Evades Install-Script Defenses via BTree.prototype.set()
indexed-btree npm Campaign (TL-2026-2590) is a high-severity supply-chain compromise, first published 2026-09-20. It has no confirmed attribution, affects npm registry indexed-btree, maps to 14 MITRE ATT&CK techniques (T1027, T1036.005, T1059.007), and is covered by 9 detection rules and 19 indicators of compromise.
Key facts for TL-2026-2590
- Threat ID
- TL-2026-2590
- Severity
- HIGH
- Status
- ACTIVE
- Category
- SUPPLY_CHAIN
- First published
- 2026-09-20
- Last reviewed
- 2026-09-20
- Attribution confidence
- LOW
- Motivation
- UNKNOWN
- Target sectors
- technology, software development, cross-sector
- Target regions
- Global
- Detection rules
- 9
- Indicators of compromise
- 19
Malware and tooling in indexed-btree npm Campaign
Malware and tooling: -1003952553968, 0xE390863Dac96a7118C71227C2b099B50cF602D31, 8961878831:AAG4WTbRUcbXI5UCaN4VXK8k57ghqqkg_qI, C0B8XPGCKQS, bad013df6eec5d686f4cc8551e0a5c87a0135164bdd1dafb1c75141d1b526702, xoxb-11307403103236-11289767127959-U58yt3zLurAvVoZOf0OBtxCW
Checkmarx Zero identified indexed-btree and nine related npm packages (combined ~5.3M+ weekly downloads) that plant a malware loader inside the runtime-executed BTree.prototype.set() method instead of install lifecycle scripts, evading npm v12's script-approval gate and static/taint-analysis scanners. Once triggered by a specific key value, the loader exfiltrates host data via Slack and Telegram and pulls an X25519/AES-protected second-stage payload from an Ethereum Sepolia smart contract acting as blockchain-based C2.
How indexed-btree npm Campaign works
In September 2026, Checkmarx Zero researchers disclosed a supply-chain campaign built around the npm package indexed-btree, which impersonates the popular sorted-btree library (impersonated package reached roughly 2 million weekly downloads at its peak) and nine sibling packages published from the same operator: ordered-kv-index, btree-leaderboard, priority-slot-queue, btree-range-store, btree-core, btree-time-index, btree-lru-cache, neighbor-key-map, and sliding-score-window, together accounting for over 5.3 million combined weekly downloads. All ten were removed from the npm registry following disclosure.
The campaign's defining innovation is where the malicious logic lives. In June 2026, GitHub/npm announced that npm v12 would require explicit developer approval before executing dependency lifecycle scripts (preinstall, install, postinstall), a measure that rolled out fully by July 2026 specifically to block install-time supply-chain malware. indexed-btree ships with no lifecycle scripts at all, so npm's approval gate never engages. Instead, the operators grafted the loader directly into BTree.prototype.set(), the library's core write method that every consuming application calls constantly during normal operation. The public GitHub repository (org INDEXED-BTREE, maintainer account charlessadler25, whose profile photo is AI-generated) never contains the malicious code; the divergence exists only in the tarball published to the npm registry, which ships an additional extended/ directory containing the obfuscated first-stage loader sharedLoad.min.js. The loader activates only when the host application calls .set() with a key that loosely equals 100, a narrow trigger condition designed to evade both static/taint-analysis tooling and sandboxed dynamic-analysis runs that don't happen to exercise that exact code path.
Once triggered, the first stage collects system reconnaissance data (OS architecture, hostname, CPU details, memory, uptime) and exfiltrates it via a hardcoded Slack bot token/channel and a hardcoded Telegram bot token/chat ID. It then spawns a detached Node child process (stdio: 'ignore', windowsHide: true) that polls a smart contract deployed on the Ethereum Sepolia testnet, reading state written by the operators through the contract's setter functions. Communication uses X25519 elliptic-curve Diffie-Hellman key exchange against a hardcoded operator public key to derive a shared secret, which is used to AES-decrypt a second-stage payload stored as on-chain ciphertext. This blockchain-based C2 design leaves no domain to sinkhole and no server to seize. The malware can self-delete and remove the runtime trigger from the package's code to eliminate forensic traces.
Fabricated commit history on the GitHub organization dates back to December 2025, with periodic housekeeping and documentation commits through mid-2026 used to build apparent legitimacy for the package ahead of the malicious tarball's wide distribution. Snyk published an advisory marking all versions of indexed-btree as malicious (CWE-506, Embedded Malicious Code) on September 7, 2026; Checkmarx Zero published the full technical breakdown on September 17, 2026, attributing the operation to an Ethereum wallet holding 109 ETH (~€230,933 at disclosure) with no confirmed direct theft and no named threat actor or group. BleepingComputer's public report on September 20, 2026 confirmed all ten packages had been removed from npm.
MITRE ATT&CK techniques used in TL-2026-2590
Defense Evasion
T1027 Obfuscated Files or Information; T1036.005 Match Legitimate Resource Name or Location; T1070.004 File Deletion; T1140 Deobfuscate/Decode Files or Information
Execution
Command and Control
T1071.001 Web Protocols; T1102.002 Bidirectional Communication; T1573.002 Asymmetric Cryptography
Discovery
T1082 System Information Discovery
Initial Access
T1195 Supply Chain Compromise; T1195.001 Compromise Software Dependencies and Development Tools
Exfiltration
T1567.004 Exfiltration Over Webhook
Resource Development
Affected products and versions in indexed-btree npm Campaign
- npm registry — indexed-btree
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — ordered-kv-index
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — btree-leaderboard
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — priority-slot-queue
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — btree-range-store
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — btree-core
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — btree-time-index
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — btree-lru-cache
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — neighbor-key-map
Vulnerable versions: all published versions
Fixed in: removed from npm registry - npm registry — sliding-score-window
Vulnerable versions: all published versions
Fixed in: removed from npm registry
Remediation for indexed-btree npm Campaign
Patches
- No vendor patch applies; all ten malicious packages were removed from the npm registry and must be fully uninstalled and purged from lockfiles/caches
Immediate actions
- Audit lockfiles, SBOMs, container/registry mirrors, and CI caches for any of the ten known-malicious package names: indexed-btree, 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
- Preserve node_modules and npm cache directories as forensic evidence before remediation; the malware can self-delete and remove its own trigger
- Block/monitor egress from build and CI systems to the identified Slack bot token/channel, Telegram bot/chat ID, and Sepolia RPC endpoints (Alchemy, Infura)
- Rotate npm publish tokens, GitHub/GitLab/Azure DevOps credentials, cloud provider keys, and CI/CD secrets on any system that ever installed one of the ten packages
- Hunt for orphaned/detached Node child processes spawned with stdio:'ignore' and windowsHide:true, and for the file path /extended/sharedLoad.min.js
Workarounds
- Do not reinstall indexed-btree or any of the nine related packages under any version; migrate to the legitimate sorted-btree library or another actively-maintained B-tree/ordered-map implementation
Longer-term hardening
- Adopt runtime behavioral monitoring (EDR/RASP) for build and developer environments, since npm's install-script-blocking (npm v12) does not cover malicious logic embedded in a dependency's normal runtime code path
- Pin dependency versions and diff SBOMs on every update rather than trusting install-time scanning alone
- Monitor developer and CI hosts for anomalous outbound connections to messaging-platform bot APIs (Slack, Telegram) and blockchain RPC providers, which are not typical developer-tooling traffic
Weaknesses (CWE) in indexed-btree npm Campaign
CWE-506
Timeline of indexed-btree npm Campaign
- Earliest fabricated commits pushed to the GitHub INDEXED-BTREE organization under maintainer account charlessadler25 (AI-generated profile photo) to build the package's apparent legitimacy.
- indexed-btree version 2.1.1 published to npm; the published tarball (not the public repo) contains the extended/sharedLoad.min.js loader and the BTree.prototype.set() trigger.
- GitHub/npm announce npm v12 will block dependency lifecycle scripts (preinstall/install/postinstall), Git dependencies, and remote URLs unless explicitly approved by the project.
- Housekeeping commits pushed to the public GitHub repository to preserve the appearance of active, legitimate maintenance.
- npm v12 rolls out, enforcing explicit approval for install-time lifecycle scripts; indexed-btree's runtime-only trigger design evades this control entirely since it ships no lifecycle scripts.
- Further documentation commits made to the public repository, which never contains the malicious loader code found only in the published npm tarball.
- Snyk publishes a security advisory marking all versions of indexed-btree malicious under CWE-506 (Embedded Malicious Code), rated high impact across confidentiality, integrity, and availability.
- Checkmarx Zero publishes the full technical breakdown, identifying the BTree.prototype.set() trigger, the Slack/Telegram exfiltration channels, the X25519/AES-protected Sepolia smart-contract C2, and attribution to a wallet holding 109 ETH.
- BleepingComputer reports the campaign publicly; all ten related packages (indexed-btree, 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) have been removed from the npm registry.
Sources cited for indexed-btree npm Campaign
- Malicious npm packages evade install-script defenses at runtime
- Supply Chain Attack Using Ethereum Smart Contracts to Distribute Multi-Platform Malware (indexed-btree technical breakdown)
- Malicious indexed-btree npm Package Bypasses npm v12 Security
- npm indexed-btree Malware Bypasses Install-Script Controls
- Malicious npm Packages Bypass Install-Script Defenses at Runtime
- Malicious npm packages evade install-script defenses at runtime
- Malicious npm packages evade install-script defenses at runtime - Threat Radar
More in supply chain
- GHAPPIER Loader: npm Trusted-Publishing Abuse Compromises @dforge-core/dforge-mcp
- Rust Team Members and Popular Crate Owners Targeted via Fake Job Video Calls (North Korea-Linked)
- GHAPPIER Loader: npm Supply-Chain Compromise of @dforge-core/dforge-mcp Linked to DPRK PolinRider Campaign
- Brevo Supply-Chain Attack: Stolen Cloudflare API Key Deploys Malicious Edge Worker, Backdoors 100,000+ Websites via ClickFix and a Rogue WordPress Plugin
- PhantomRaven: LLM-Generated npm Information Stealer Used for Bug Bounty Hunting
Detection coverage for TL-2026-2590
As of 2026-09-20, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-2590 across Splunk SPL, Microsoft KQL and Sigma, covering 19 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.