Malicious npm package hid malware in runtime code

Malicious npm package hid malware in runtime code

Checkmarx found a malicious npm package, indexed-btree, that ran its malware from ordinary library code instead of install scripts, and it was downloaded millio…

A malicious npm package called indexed-btree carried its malware inside ordinary library code that runs while an application is working, rather than in the install-time hooks that security teams have learned to watch. The package was identified by Checkmarx, a software supply chain security company, which said the code imitated sorted-btree, a legitimate indexing utility built around a B-tree, an ordered data structure that applications use to store and search sorted information quickly. The package and its associated GitHub repository are no longer available for download from npm.

npm is the main public registry from which JavaScript and Node.js projects download ready-made code written by other people. For years, one of the simplest ways to attack that ecosystem has been a lifecycle script, a short instruction such as preinstall or postinstall that runs automatically when a package is installed. Checkmarx noted that these hooks have honest uses, such as compiling code, seeding a database with starting values or setting up configuration files, but that attackers have frequently abused them to run malicious code on a machine without the user agreeing to it. npm version 12 introduced a security change to stop lifecycle scripts such as preinstall and postinstall from executing automatically. The indexed-btree campaign appears to be a direct answer to that change: the package does not rely on those hooks at all and instead runs entirely from application code at runtime.

The loader is hidden inside a method named BTree.prototype.set(), a normal-looking function that a developer's application calls when it stores a value in the data structure. When that function runs, it triggers a second file, sharedLoad.min.js, a JavaScript payload that embeds the obfuscated (deliberately scrambled so that it is hard to read) first stage of the malware. According to Checkmarx, that stage fingerprints the machine it is running on, reports what it finds to a hard-coded Slack channel and Telegram bot, then uses a technique called EtherHiding to fetch encrypted blobs of code from a smart contract deployed on the Sepolia testnet, an Ethereum test blockchain. The blobs are merged to build the second-stage payload. Once that is done, the malware deletes its own artifacts and removes the trigger from the package code, so the trail is harder to follow.

Statistics cited by Checkmarx show that indexed-btree was first uploaded to the npm registry on June 18, 2026 by an npm user named charlessadler25, and that it amassed millions of downloads in a short span of time. The campaign may also have earned the operator money: Checkmarx said it generated around EUR 230,933.57 in cryptocurrency, equivalent to 109 ETH.

Checkmarx said indexed-btree is one of many npm packages tied to the same operation, all of which have since been removed from npm: 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 mutex-forge.

To counter the threat, Checkmarx recommends that developers not rely on install-time scanning and on blocking lifecycle scripts alone, but also use runtime behaviour analysis, meaning tools that watch what software actually does while it is running. Ensar Seker, chief information security officer at SOCRadar, said in a statement shared with The Hacker News that the campaign shows attackers adapting almost immediately to stronger software supply chain defences: npm improved install-time security by restricting dependency lifecycle scripts, and this operation pushed malicious execution into legitimate-looking runtime functionality instead. Seker's broader point is that security controls change attacker behaviour rather than eliminate the underlying threat. Blocking lifecycle scripts is an important improvement, he argued, but attackers will keep searching for alternative execution paths, so defenders need layered controls able to detect malicious behaviour before installation, during execution and after deployment.

Separately, the security firm Socket said it deleted malicious code in the dev-main version of visanduma/nova-two-factor, a package on Packagist, the main public registry for PHP code, with more than 700,000 cumulative downloads. Socket linked that intrusion to an ongoing campaign it calls PolinRider, which it says is associated with North Korea. A defining trait of the campaign is that the operators compromise developer accounts and inject malicious content into source code repositories, then use routine developer actions such as cloning a repository or opening it in an integrated development environment (IDE, the program in which code is written and run) as the trigger that starts the infection chain. According to Socket, this often involves rewriting Git history, concealing payloads inside configuration or font files, setting up malicious VS Code tasks that run by themselves, and relying on takedown-resistant delivery such as EtherHiding and its stealth-focused successor NullReceiver to fetch staged payloads through a blockchain.

Socket security researcher Karlo Zanki said analysis of the Visanduma GitHub organisation indicates that its repositories have been compromised since mid-June 2026, with the malicious changes introduced through the LaHiRu developer account. One notable shift in this iteration, according to Socket, is the direct insertion of heavily obfuscated JavaScript into index.php and its execution through PHP's shell_exec() function. That approach lets a PHP entry point start the JavaScript infection chain, and Socket reads it as a sign that the operators adapt their execution method to whichever project they have compromised instead of using one fixed delivery path.

Socket also drew a wider conclusion: package registry compromise is often a consequence of a broader Git-based intrusion rather than the campaign's main objective. The operators use ordinary source code collaboration to reach developer environments, spread into additional repositories and keep access over time. A compromised source repository gives them the chance to infect contributors, reach private projects and move through normal development workflows, and publishing a package becomes just one more distribution path when that repository produces a new release.

For website owners and IT teams the practical lesson is that modern sites are assembled from dozens, sometimes hundreds, of third-party components, and both of these cases show that a clean installation is not proof of safety. Scanners that only look at code when it is installed can miss malware that waits until the application is actually running, and a source repository can be compromised long before any package is published. Teams should keep an inventory of what their sites and applications depend on, watch for unexpected behaviour from their servers such as outbound traffic to services nobody configured, and protect developer

How to Protect Yourself

  1. Ask whoever builds or maintains your website which outside pieces of code it uses, and how they check those pieces for security problems.
  2. Keep your website platform, plugins and themes updated automatically, but only from the official source, and remove any add-on you no longer use.
  3. Do not install code packages, browser extensions or tools with names very similar to a popular one until you are sure who published it.
  4. Ask your hosting or IT provider whether your site's software is watched while it is running and not only when it is installed.
  5. Turn on two-factor authentication (a second code at login) for every account that can publish code or manage your website.
  6. If your site suddenly sends traffic to services you never set up, or your hosting bill jumps for no clear reason, report it to your provider straight away.

Terms Explained

  • npm The main public online library from which JavaScript and Node.js projects download ready-made pieces of code written by other people.
  • lifecycle script A short instruction inside a code package that runs by itself while the package is being installed, without the person installing it doing anything.
  • package registry An online catalogue where developers publish code packages and others download them, such as npm for JavaScript or Packagist for PHP.
  • B-tree A way of organising stored data so that a program can find and sort items quickly, similar to a well-ordered filing cabinet.
  • EtherHiding A trick in which malicious code is stored on a blockchain, a shared public record, so that it cannot easily be taken down.
  • smart contract A small program that lives on a blockchain and runs automatically, which attackers can use as a hidden storage place for code.
  • obfuscated Written in a deliberately scrambled way so that a human reader cannot easily understand what the code does.
  • IDE An integrated development environment, the software program in which developers write, run and test their code.

Related AEU services

  • AEU-I IT and security consulting