Runtime-Triggered npm Malware Slips Past Install-Script Protections

A malicious npm campaign hides its payload in normal library functions, bypassing install-script controls and using runtime triggers, reconnaissance, and blockchain C2.

Text generated by artificial intelligence, published without human review. AI transparency

Runtime-Triggered npm Malware Slips Past Install-Script Protections
Malware

Illustrative image generated with AI

Listen to this articleAudio edition · 11 min

A malicious npm campaign has shifted its execution logic away from installation hooks and into ordinary library behavior, allowing packages to pass controls designed to block dangerous lifecycle scripts.

Checkmarx researchers centered their investigation on indexed-btree, a package crafted to resemble the legitimate sorted-btree library. According to reporting on the researchers’ findings, indexed-btree reached approximately two million weekly downloads, creating substantial exposure across developer environments.

The package does not rely on preinstall, install, or postinstall. Instead, its loader is hidden inside BTree.prototype.set(), a normal B-tree operation, and activates during application execution when it receives a specific key value.

That design targets a gap between installation security and runtime monitoring. An npm package can install without requesting permission to execute a lifecycle script, yet still run malicious code later when an application calls its exported functions.

The malicious path begins inside a routine library method

The initial installation of indexed-btree appears clean because the package does not use dependency lifecycle scripts to launch its payload. The malicious behavior starts only when software using the library calls BTree.prototype.set() with the required trigger value.

The exact trigger key has not been disclosed. The affected package versions have not been disclosed either, making inventory-based scoping more difficult for organizations that retained multiple releases in package caches or lockfiles.

Once triggered, the method invokes sharedLoad.min.js, which contains an obfuscated first-stage payload. Placing this loader inside a frequently used data-structure operation helps conceal it among code that appears consistent with the package’s advertised purpose.

Checkmarx assessed the technique as capable of evading many static scanners and conventional taint-analysis systems. Those tools may inspect installation hooks, suspicious subprocess creation, or obvious flows from untrusted inputs to dangerous functions. Here, the malicious branch is buried within an apparently legitimate API and remains dormant until runtime conditions are satisfied.

The operators also built a broader appearance of legitimacy around the package. They created a convincing GitHub repository, populated it with a commit history designed to look authentic, and maintained a curated developer account. These signals can influence both automated reputation systems and developers conducting a quick manual review.

npm v12 controls do not cover normal runtime execution

In June 2026, GitHub announced npm security measures intended to address supply-chain attacks that had repeatedly affected open-source ecosystems since late 2025. Among those measures, npm v12 blocks dependency lifecycle scripts unless a user explicitly authorizes them.

The protections also restrict automatic retrieval of dependencies from Git repositories or remote URLs without permission. These changes reduce the effectiveness of packages that execute immediately during installation or fetch external code through dependency declarations.

indexed-btree avoids that security boundary altogether.

Because its malicious loader is part of the package’s ordinary runtime path, npm does not encounter an install script that requires approval. Installation can therefore finish without producing the warning or authorization step that defenders might expect from a conventional malicious package.

This does not indicate a bypass of npm v12 through a software vulnerability. Rather, it exposes the limits of a control focused on one execution stage. Lifecycle-script restrictions can stop unapproved installation behavior, but they cannot determine whether every callable function in a dependency is safe.

A successful, warning-free installation is therefore not evidence that the installed code is benign.

Reconnaissance leads to an encrypted blockchain payload

After activation, the malware inventories the host. The collected information includes:

  • System architecture
  • Hostname
  • CPU details
  • Memory information
  • System uptime

It exfiltrates that data through hardcoded Slack and Telegram channels. Specific channel identifiers, destinations, and network indicators have not been disclosed.

For command and control, the operation queries an Ethereum smart contract deployed on the Sepolia test network. This architecture allows the operators to store or distribute payload material through blockchain infrastructure rather than depending exclusively on a conventional command-and-control server.

The malware uses X25519 key exchange to derive an AES key. It then decrypts a second-stage payload retrieved from the smart contract. The contents and full capabilities of that second stage have not been disclosed, so confirmed impact should not be extended beyond the observed delivery and execution mechanism.

Investigators also identified an Ethereum wallet linked to the operation containing 109 ETH. There is no established evidence that those funds came from cryptocurrency theft or from systems compromised through these packages.

The malware additionally includes an operator-controlled cleanup function. When activated, it can delete its files and remove the malicious trigger from the package source. That capability may leave a previously affected environment looking clean during a later inspection, particularly if relevant process, network, and filesystem telemetry was not retained.

Nine related packages expanded the campaign’s reach

Checkmarx connected nine additional npm packages to the same operation. All nine were removed from npm after discovery.

Package Reported downloads
ordered-kv-index 448,184
btree-leaderboard 493,685
priority-slot-queue 402,860
btree-range-store 468,092
btree-core 1,951,274
btree-time-index 425,312
btree-lru-cache 372,185
neighbor-key-map 366,019
sliding-score-window 448,024

The removal status of indexed-btree itself has not been specified. Its reported figure of approximately two million weekly downloads also should not be directly compared with or added to the other packages’ download totals, which are presented as reported download counts without the same weekly qualifier.

Download statistics establish distribution, not compromise. They do not reveal how many downloads produced installations, how many applications called the modified method, or how many executions supplied the required trigger key.

Nevertheless, the package names suggest targeting of software-development use cases involving indexes, queues, caches, maps, and scoring systems. The potential exposure includes developer workstations, CI runners, build servers, and other systems where npm dependencies execute with access to source code or credentials.

The main risk extends beyond basic host profiling

No CVSS score or vendor severity rating has been assigned. This is a malicious-package campaign rather than a conventional vulnerability with a published CVE identifier.

Operationally, the risk is high because the code combines broad distribution, delayed runtime activation, host reconnaissance, encrypted second-stage delivery, and evidence removal. A compromised development environment may expose more than the system metadata directly collected by the first stage.

Depending on local permissions, a malicious second stage could potentially reach package-publishing tokens, source-control credentials, cloud keys, CI secrets, signing material, or application configuration. Access to those assets has not been confirmed, but organizations should include them when determining what was available to an affected process.

Self-cleaning also complicates incident scoping. The absence of malicious files during examination does not prove that execution never occurred.

Affected organizations should preserve evidence before rebuilding

Organizations should search dependency inventories, lockfiles, internal registries, build caches, container layers, and software bills of materials for indexed-btree and all nine linked names. Because affected version ranges are unknown, investigators should not assume that a particular release is safe without independently validating its contents.

Before rebuilding systems, responders should preserve available package artifacts, process telemetry, command histories, network logs, CI records, and filesystem evidence. The cleanup mechanism may otherwise erase information needed to establish whether the runtime trigger fired.

Recommended response measures include:

  1. Isolate potentially affected development and build systems.
  2. Rotate every secret accessible to those environments, including source-control, registry, cloud, deployment, and CI credentials.
  3. Restore from a known-safe backup or clean image rather than trusting the malware’s own removal behavior.
  4. Investigate runtime connections involving Slack, Telegram, and Sepolia infrastructure, while recognizing that legitimate tools may also use those services.
  5. Look for unexpected X25519 key exchange and AES decryption activity associated with Node.js or affected build processes.
  6. Review application execution, not only package installation, for calls into altered library methods and loading of sharedLoad.min.js.
  7. Add sandboxed runtime analysis to package screening, especially when dependencies contain obfuscated code or modify common API paths.

Blocking lifecycle scripts remains useful, but it addresses only one point in a dependency’s execution chain. This campaign demonstrates that malicious maintainers can move activation into the application itself, where package code inherits the trust and access already granted to normal software.

Read next

Sources

This article is an original reworking based on the sources below.

Related topicsnpm malwareruntime-triggered malwaresoftware supply chainnpm securitymalicious packagesblockchain command and controlinstall-script bypass
Back to home