← All articles

npm malware hides in runtime code, not install scripts

npm malware hides in runtime code, not install scripts

A new wave of npm malware has been hiding inside the everyday code of a popular library rather than in the scripts that run when it is installed, according to security researchers at Checkmarx. The package is called indexed-btree, and it was published to npm, the public catalogue that software developers use to download ready-made pieces of code into their projects, while impersonating sorted-btree, a legitimate library with a very similar name. Checkmarx says the fake package had already accumulated two million weekly downloads.

The finding matters because it targets a defence that the npm ecosystem put in place only recently. In June 2026, GitHub announced a set of npm security measures aimed at preventing the supply chain attacks that have shaken open source projects repeatedly since late 2025. A supply chain attack is one in which attackers do not break into a victim directly, but instead compromise a component that many victims trust and install. One of the key measures blocks dependency lifecycle scripts, the small pieces of code named preinstall, install and postinstall that run automatically during installation, unless they are explicitly approved. Other measures stop npm from automatically pulling dependencies from Git repositories or remote web addresses without permission.

indexed-btree sidesteps all of that by not using an installation script at all. Instead, the loader is hidden inside the library's own BTree.prototype.set() method, which Checkmarx describes as the main function that every user of the library would call constantly. That method does nothing suspicious while the package is being installed; it only acts at runtime, meaning while the application is actually running, and only when it is called with one specific key value. As a result, the installation looks completely clean and triggers none of npm version 12's approval mechanisms. The hidden loader is a file called sharedLoad.min.js, which contains the first stage of the malware in an obfuscated form, meaning it has been deliberately written in a confusing way so that its real purpose is hard to read.

Checkmarx notes that this is a well-built way to slip past standard taint-analysis tools, which follow how data moves through a program, and past most static scanners, which inspect code without ever executing it. Because the harmful behaviour appears only when the application runs, tools that examine a package at install time see nothing out of the ordinary.

Once it is running, the malware gathers details about the machine it has landed on, including processor architecture, hostname, CPU, memory and uptime, and sends that information out through hardcoded Slack and Telegram channels. It also polls a smart contract on the Sepolia test network, an Ethereum-based test environment, to retrieve its command-and-control information, meaning the instructions that operators send to infected machines. It uses X25519 key exchange to derive an AES key, two cryptographic methods used to create and swap the secret codes that lock and unlock data, and then decrypts a second-stage payload that is stored inside that contract. The operators can also choose to end the attack: the malware is able to delete its own files and remove the malicious trigger from the package code, wiping the traces it left behind.

The researchers report that the attackers went to considerable lengths to make the project look trustworthy, building a legitimate-looking GitHub repository, filling in its commit history and curating the developer account that published it. The campaign may also have been profitable. According to Checkmarx, the attackers use a wallet holding 109 ETH, the cryptocurrency of the Ethereum network. The report does not say those funds came from cryptocurrency theft, and that link has not been established.

Checkmarx identified nine further npm packages connected to the same operation and reports that they have now been removed from npm. They too reached substantial download counts: 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) and sliding-score-window (448,024).

The practical lesson the researchers draw is that install-time scanning on its own is not enough, because a package can behave perfectly during installation and turn hostile much later. Checkmarx advises adding runtime behavioural analysis, which means watching what installed code actually does while it runs. Anyone who installed indexed-btree or any of the nine packages listed above is advised to rotate all secrets, in other words to replace every password, access token and key that the affected machine could have seen, and to restore the development environment from a safe backup rather than trying to clean it in place. For teams who want an independent review of what runs inside their own systems, AEU-I offers security-first IT, infrastructure and consulting, which is precisely the kind of check this incident shows the value of.

Also available in: DeutschItalianoShqip