Sonatype’s research team reported on November 4 that a malware loader tied to the PolinRider campaign has resurfaced inside 12 npm package releases across 10 hijacked packages. The loader asks the Ethereum blockchain where to fetch its next stage, so the attacker can move the command server without republishing a single package. Sonatype tracks the event as sonatype-2026-010515 and lists no CVE. The affected packages are mostly scoped names such as @adminide-stack/*, plus server-hemera-mongo, cdeops, @cdmbase/wiki-browser, and @pubngo-stack/help-browser.
How the Loader Finds Its Server
The injected code runs when the application loads the compromised module, not at install time. Sonatype says the manifests contain no install or postinstall hooks, so turning off npm install scripts does nothing here. Six of the releases hide the loader behind Base64 and eval(atob(...)), and six use a character-permutation bootstrap that builds code through the JavaScript Function constructor.
Once running, the loader queries public Ethereum RPC endpoints, with a Blockscout API fallback, for a transaction sent by one hard-coded wallet, 0x1eef0849eda15d87f64e51c73c8442cf3c8bcef3. It reads the first four bytes of the transaction’s recipient address as a primary IPv4 address and the next four as a secondary one. It then downloads XOR-encoded JavaScript from the primary address over plain HTTP on TCP port 443, using the paths /0x/cls and /0x/ls. The first path’s output goes to eval in the app process and to a detached node -i process, while the second goes only to the detached process. To change servers, the operator just sends another transaction from the same wallet.
What Sonatype Does and Doesn’t Say
Sonatype links these releases to earlier PolinRider activity because the same wallet shows up in GitGuardian’s October 27 report, where it served as the Ethereum resolver for loaders in compromised GitHub repositories. Greenflagged reported 95.135.181.151 as the advertised server on November 3, and GitGuardian had listed the same address on port 443 as a fallback. Sonatype is careful, though: it says the overlap does not definitively establish that PolinRider and the GhostAction campaign share an operator, and it names no threat actor.
The write-up also leaves real gaps. It does not give download counts, explain how the packages were hijacked, say when the malicious versions were published, or say whether npm has removed them. Its table lists 12 releases, but its remediation section refers to “all eight versions,” so use the table as the list to check against.
What To Do Now
- Search lockfiles, internal mirrors, caches, and build records, including transitive dependencies, for the packages and versions in Sonatype’s table, and block them in your repository manager or dependency firewall.
- Do not stop at a lockfile hit. Work out whether the code actually ran, because a lockfile entry doesn’t prove execution and an import error doesn’t prove it didn’t.
- If it ran, treat the host as compromised. Look for connections to 95.135.181.151, requests to
/0x/clsor/0x/ls, and detachednode -iprocesses launched by another Node process, then rotate any reachable publishing tokens, repository access, cloud keys, and CI secrets. - Pin to versions you have independently verified as clean, since Sonatype names no replacement versions.
This is the same pattern we described in 14 Trojanized npm Packages Are Smuggling an AI-Powered Linux Backdoor: the risk sits in dependencies that load at runtime, not in the install step. If you want a second set of eyes on how a Node project pins, audits, and builds its dependencies, that is part of our web application development work.
Sources
- PolinRider Loader Reappears in Hijacked npm Packages (Sonatype Research Team, November 4, 2026)
