Hacking and Exploits Self Hosted

PolinRider loaders spread through hijacked npm packages

PolinRider loaders spread through hijacked npm packages

Sonatype Research Labs found 10 npm packages with hidden malware loaders that used the Ethereum blockchain to locate a server and fetch more code. The finding was confirmed on November 4, 2026, and Sonatype tracks it as sonatype-2026-010515 with a severity score of 8.7.

How the hijacked packages were altered

The compromised packages served different purposes. Some were tied to Redux, health APIs, browser activity tracking, utilities and server examples. The affected packages were @adminide-stack/client-redux, @adminide-stack/health-api-server, @adminide-stack/user-activity-browser, @adminide-stack/utils, server-hemera-mongo, cdeops, @adminide-stack/forms-core, @adminide-stack/yantra-help-browser, @cdmbase/wiki-browser and @pubngo-stack/help-browser.

Six releases hid the loader with Base64 and eval(atob(…)). The other six used a character-permutation trick and the JavaScript Function constructor. Sonatype’s technical write-up lists every affected version, including @adminide-stack/utils 0.0.16-129 and 0.0.16-130, plus cdeops 13.5.31.

Blockchain lookup and server retrieval

Each loader queried public Ethereum RPC servers for a transaction sent by one fixed wallet, 0x1eef0849eda15d87f64e51c73c8442cf3c8bcef3. If those servers did not respond, the code fell back to the Blockscout API. The loader treated the first four bytes of the transaction recipient address as one IPv4 address and the next four bytes as a backup address.

The malware then downloaded XOR-encoded JavaScript from the first address over plain HTTP on port 443. It used the paths /0x/cls and /0x/ls. Code from /0x/cls ran in the app with eval and also in a detached node -i process, while code from /0x/ls ran only in the detached process so it could keep running after the app closed.

The attacker could post a new transaction with a new server address and leave the npm packages untouched. Blocking one server did not stop the malware from finding another one.

Why the loaders mattered

Most npm malware depends on preinstall or postinstall hooks, and many teams disable those hooks. These packages did not use such hooks. The bad code ran when the app loaded the package, and in server-hemera-mongo it ran when the service started because the code sat in dist/main.js.

Turning off install scripts offered no protection in this case. A similar pattern had appeared in earlier PolinRider activity that hid JavaScript loaders in open-source projects and used blockchain services to fetch a second stage. The question for defenders was whether the package code actually ran on a developer laptop, a build server or a live service.

Links to earlier PolinRider activity

Sonatype found the same wallet across all 12 releases. GitGuardian’s GhostAction and PolinRider report from October 27, 2026, used that same wallet as the Ethereum resolver in PolinRider loaders found in hacked GitHub repositories. Those older loaders also pulled /0x/cls and /0x/ls on port 443.

The server data lined up with that pattern. Greenflagged decoded the wallet’s transactions from the npm releases and identified 95.135.181.151 as the advertised server on November 3. GitGuardian had already listed that IP as a fallback server in a PolinRider persistence script.

Attribution and related findings

Researchers urged caution on attribution. Sonatype said the link does not prove that PolinRider and GhostAction share one operator. GitGuardian’s working view is that GhostAction’s operator copied a public PolinRider launcher. The GhostAction campaign has hit tens of thousands of GitHub repositories, so the two groups may share many victims.

PolinRider also predates the current npm campaign. OpenSourceMalware traced PolinRider code to npm packages from May 2025, months before the first known victims in January 2026. That payload included a remote access tool and a Python stealer aimed at browsers, wallets, Git and cloud storage.

A Sonatype-linked community write-up said later stages install a Node remote access trojan that persists through startup files for tools such as VS Code, Cursor, Discord and GitHub Desktop.

Detection and response steps

Search package-lock.json, yarn.lock, pnpm-lock.yaml, internal mirrors, caches and build records for the 12 bad releases. Remove them and stop mirrors from serving them. Keep a copy for investigation and move to versions that have been checked manually.

A lockfile entry alone does not show that the code ran. Check which entry point the app loaded and match it with process and network logs. An import error also does not prove safety, because the bad code may have run before the failure.

If the code ran, treat the host as compromised. Look for detached node -i processes started by another Node process and for plain HTTP requests to port 443 that use /0x/cls or /0x/ls. Payload requests carry a Sec-V header, which reads A10-npm_inject in the six Base64 releases, A10-II in utils 0.0.16-130 and A10-E in cdeops 13.5.31.

Rotate any secrets the affected process could reach. That includes npm publishing tokens, source repository access, cloud keys and CI secrets. Logs, not package lists alone, show what happened. The Sonatype Guide security event offers further detection help.

Leave a Reply

Your email address will not be published. Required fields are marked *

🧰

Free Tools: IP, DNS, SSL

40+ free network and other tools in one place. No signup. Click explore or visit https://technochat.in/tools

Explore