PolinRider npm Attack Uses an Ethereum Wallet to Hide C2
Sonatype says attackers slipped runtime loaders into 10 hijacked npm packages, using an Ethereum wallet as a movable pointer to command-and-control infrastructure, no install script required.

Sonatype Research Labs says a campaign it tracks as PolinRider published malicious runtime loaders in 12 npm releases spanning 10 hijacked packages on November 3, 2026 — some of which hadn't been updated in years. Instead of the usual install-script trick, the loader is wired directly into code the package already executes, so it fires the moment the package loads. It then reads the latest transaction sent from a specific Ethereum wallet, decodes a command-and-control (C2) address hidden in that transaction, and fetches its next-stage payload from there. Sonatype links the activity to PolinRider, a loader family it has tied in earlier reporting to the North Korea-linked Lazarus Group.
What happened, in plain terms
On November 3, 2026, Sonatype Research Labs identified concealed loaders added to 12 releases across 10 npm packages that had previously been taken over by attackers — a technique the firm calls hijacking, where a maintainer account or publishing credential is compromised and used to push a new, malicious release of an otherwise legitimate package. Sonatype published its technical write-up, "PolinRider Loader Reappears in Hijacked npm Packages," the following day, tracking the find internally as sonatype-2026-010515.
The detail that makes this incident worth a developer's attention isn't the headline count of affected packages — plenty of npm supply-chain incidents involve more. It's the retrieval mechanism. Rather than hardcoding a domain or IP address that could be sinkholed or taken down, the loader looks up the most recent transaction sent from a specific, hardcoded Ethereum wallet address, decodes an IPv4 address out of the transaction data, and treats that as its live C2 endpoint. The operator can redirect every infected install to a brand-new server at any time just by broadcasting a new blockchain transaction — no npm publish, no version bump, nothing for a registry or a security scanner to catch mid-campaign.
- Campaign: PolinRider (tracked by Sonatype Research Labs)
- Releases/packages: 12 malicious releases across 10 hijacked npm packages
- Publish date of malicious releases: November 3, 2026
- Sonatype tracking ID: sonatype-2026-010515
- C2 resolver wallet: 0x1eef0849eda15d87f64e51c73c8442cf3c8bcef3 (Ethereum)
- Reported C2 IP: 95.135.181.151 (per Sonatype, citing third-party reporting)
- Attribution: Sonatype links PolinRider to the North Korea-linked Lazarus Group, while cautioning that "Lazarus" is often used as an umbrella label for related DPRK activity rather than a precise actor identification
Timeline: how PolinRider got here
PolinRider isn't a one-off. Sonatype's public record shows the loader family resurfacing in npm several times over the course of 2026, each time with small technical variations:
| Date | Sonatype finding | Technique |
|---|---|---|
| May 21, 2026 (updated June 4) | Hijacked release of @common-stack/generate-plugin nearly delivers a PolinRider-linked RAT; 13 compromised versions eventually identified | Payload appended to postcss.config.js, runs at install time, uses the Tron blockchain as a resilient pointer to the next stage |
| August 10, 2026 | Six npm packages (three hijacked, three newly published) found carrying the same payload | Loader reads Ethereum transactions from an attacker-controlled wallet to locate C2 servers |
| November 3–4, 2026 | 12 releases across 10 hijacked packages carry the loader covered in this article | Loader runs at module-load or app-startup time (no install script); Ethereum wallet used as a "dead-drop resolver" for the C2 address |
The common thread across all three waves is the use of a public blockchain as a lookup layer for C2 infrastructure — a technique that keeps evolving (postcss injection and Tron in the spring, Ethereum-wallet lookups by summer and fall) but keeps the same strategic goal: decouple "where the malware calls home" from "what code shipped in the package," so defenders who block one IP or domain don't actually stop the campaign.
How the loader actually works
Sonatype's November write-up is unusually specific about the mechanics, which is worth walking through because it explains why some of the normal mitigations (like disabling install scripts) don't apply here.
Across the 12 malicious releases, Sonatype found two loader variants:
- Six releases conceal the loader with simple Base64 encoding, executed via
eval(atob(...)). - Six releases use a character-permutation bootstrap built on JavaScript's
Functionconstructor. Sonatype notes the decoded payload from this variant is byte-identical to the Base64 variant once unpacked — it's the same loader, just wrapped differently.
Crucially, none of the 12 releases' manifests contain an install or postinstall hook. In cdeops, the loader sits in client.js, ahead of the normal module delegation; in the 0.0.16-130 release of @adminide-stack/utils, it's tacked on after the package's own logging code; in server-hemera-mongo, it's injected directly into dist/main.js, the bundle the package's own start script runs. In every case, the loader executes as a side effect of the package doing its normal job — importing a module, or starting a server — rather than during npm install. That's a meaningful shift from the install-script pattern that dominates most npm supply-chain writeups, and it means "we run with install scripts disabled" is not a defense against this particular loader.
The Ethereum "dead-drop" and how it resolves a C2 address
Once running, the loader queries public Ethereum RPC endpoints — falling back to the Blockscout block-explorer API if needed — for the most recent transaction sent from a specific wallet address: 0x1eef0849eda15d87f64e51c73c8442cf3c8bcef3. Sonatype describes this wallet as a "dead-drop resolver": the attacker doesn't need to control a server the loader talks to directly from the start; they just need to be able to broadcast a transaction.
The loader takes the transaction's recipient address and reads it as raw bytes: the first four bytes are decoded into a primary IPv4 address, and the next four bytes into a secondary one. Whichever address comes back, the loader then reaches out over what Sonatype describes as plain HTTP on TCP port 443 (not TLS, despite the port typically associated with HTTPS) to two specific paths, /0x/cls and /0x/ls, to fetch XOR-encoded JavaScript. Sonatype reports the decoded payload from /0x/cls gets passed both to eval inside the running application process and piped into a detached node -i interactive process, while /0x/ls goes only to the detached process. Because those child processes are unreferenced, they can keep running even after the original application exits.
The practical consequence: an operator who wants to redirect every infected install to new infrastructure doesn't need to touch npm at all. They send one Ethereum transaction, and the next time an infected package's loader runs, it finds the new address. That breaks the usual incident-response assumption that blocking or sinkholing a known-bad IP neutralizes a campaign — the "real" indicator of compromise here is the wallet, not any single server.
Sonatype also reports that the same wallet, retrieval paths, and C2 IP were separately flagged by other researchers in the days around publication: GitGuardian is cited as having linked the same wallet to PolinRider loaders found in compromised GitHub repositories in an October 27, 2026 report, and the C2 IP (95.135.181.151) is described as having been reported by a researcher identified as Greenflagged on November 3 and separately listed by GitGuardian as a fallback address in an earlier PolinRider persistence script. Sonatype is careful to frame the PolinRider connection as based on shared wallet, infrastructure, request paths, and port — not solely on code-obfuscation similarity — while explicitly stopping short of claiming this proves PolinRider and the GitHub-focused activity share the same operator.
The affected packages
Sonatype's write-up names all 10 hijacked packages and the specific malicious release versions. This is the most actionable part of the disclosure for anyone running a Node.js dependency audit:
| Package | Malicious version(s) | Loader concealment |
|---|---|---|
@adminide-stack/client-redux | 0.0.16–18 | Base64 (eval(atob(...))) |
@adminide-stack/health-api-server | 0.0.18-alpha.465 | Base64 |
@adminide-stack/user-activity-browser | 1.1.3-alpha.114 | Base64 |
@adminide-stack/utils | 0.0.16-129 | Base64 |
@adminide-stack/utils | 0.0.16-130 | Character-permutation bootstrap |
server-hemera-mongo | 0.0.15, 0.0.16 | Base64 |
cdeops | 13.5.31 | Character-permutation bootstrap |
@adminide-stack/forms-core | 5.1.9-alpha.3 | Character-permutation bootstrap |
@adminide-stack/yantra-help-browser | 12.0.194 | Character-permutation bootstrap |
@cdmbase/wiki-browser | 12.0.18-alpha.53 | Character-permutation bootstrap |
@pubngo-stack/help-browser | 12.0.23-alpha.3 | Character-permutation bootstrap |
Note that the heavy concentration of @adminide-stack scoped packages suggests the attackers gained publishing access tied to that npm scope or its maintainers specifically, rather than compromising ten unrelated maintainer accounts individually — though Sonatype's write-up doesn't spell out the access-compromise mechanism itself. As of this writing, Sonatype's post does not cite a corresponding GitHub Security Advisory (GHSA) ID for these specific releases, and a direct search of the GitHub Advisory Database for the affected package names did not surface a published advisory at the time of research. Teams should not assume automated GHSA-based scanning alone will flag these versions; checking directly against the version table above, or against Sonatype's own feed, is the more reliable path right now.
Attribution: PolinRider and the Lazarus Group
Sonatype's PolinRider campaign page attributes the loader family to the Lazarus Group, the North Korea state-sponsored threat activity cluster publicly linked over the years to the 2014 Sony Pictures breach, the 2016 Bangladesh Bank heist, and WannaCry, among other incidents. Sonatype's own FAQ adds an important nuance: "Lazarus" functions in threat-intelligence reporting as something closer to an umbrella label for a broad range of North Korean state-linked cyber activity than a single, tightly defined group, so the label doesn't necessarily pin the operation on specific individuals.
In its more narrowly technical write-ups on individual PolinRider waves, Sonatype has at times framed the Lazarus/PolinRider link as an assessment rather than a hard-confirmed fact — for example, describing the connection in its May 2026 report as a belief rather than a confirmed finding, and in the November report basing the PolinRider association specifically on shared wallet infrastructure, server paths, and ports rather than code similarity alone. Read together, the most defensible summary is: Sonatype assesses this activity as part of the PolinRider campaign, which it attributes to Lazarus Group-linked North Korean operators, with the normal caveats that apply to nation-state attribution in general.
Why this fits a broader pattern of npm supply-chain abuse
PolinRider is one entry in a wider trend this site has covered before: attackers treating widely-used, low-visibility open-source packages as a distribution channel, because a single hijacked dependency can reach every downstream project that pulls it in automatically via a lockfile update. Pandromeda's explainer on how supply chain attacks work covers the general mechanics — compromised maintainer credentials, typosquatted package names, and malicious code riding along with a routine dependency bump — all of which apply here, with the added twist of blockchain-based C2 resolution layered on top.
That twist matters operationally. Most npm malware guidance assumes defenders can eventually identify and block the C2 infrastructure a campaign uses. PolinRider's Ethereum-wallet approach is explicitly designed to defeat that assumption: the "infrastructure" that actually matters is a wallet address that can rotate its pointed-to server indefinitely, for free, without ever touching the npm registry again after the initial malicious publish.
What JavaScript and Node.js developers should do now
Given the specifics Sonatype has disclosed, there are concrete, achievable steps for any team running Node.js in production or CI:
- Check your lockfiles directly against the version table above. Search
package-lock.json,yarn.lock, andpnpm-lock.yaml— including transitive dependencies — for any of the 10 package names and the specific malicious versions listed. A dependency on an older, clean version of one of these packages is not itself a problem; the risk is the specific flagged releases. - Don't rely on "we disable install scripts" as a defense here. Sonatype is explicit that these 12 releases have no install or postinstall hooks — the loader runs when the package's code is imported or when a bundled service starts. Standard install-script sandboxing (via
--ignore-scriptsor similar) does not stop this loader. - Treat any npm package that performs blockchain or crypto-wallet lookups with suspicion unless that is an obvious, documented, core feature of the package (e.g., an actual wallet SDK). A dependency manager, logger, mongo helper, or UI component library has no legitimate reason to query Ethereum RPC endpoints or a block explorer API at runtime. Static analysis or SCA tooling that flags outbound network calls to blockchain infrastructure in otherwise-unrelated packages is a useful early-warning signal.
- Use software composition analysis (SCA) and lockfile-scanning tooling that checks against malware-specific advisory feeds, not just CVE databases — because, as noted above, this campaign had not generated a GHSA entry for these releases at the time of writing. Sonatype's own repository firewall and research feed are one option; OSV.dev's malicious-package (MAL) listings are another worth checking directly, since not every incident maps cleanly to a GHSA ID right away.
- Pin dependency versions rather than using broad semver ranges for packages your build doesn't control tightly, and review dependency updates — especially for packages that haven't shipped a release in a long time and suddenly do. Sonatype notes some of the hijacked packages here "had not been updated in years" before the malicious release, which is itself a pattern worth building into review processes: a sudden release on a long-dormant package deserves a second look before it's auto-merged.
- If you find a match, assume compromise rather than assuming safety. Sonatype's guidance is that a lockfile entry alone doesn't prove the loader executed, but an import error also doesn't prove it didn't — so look for the actual indicators: unexplained detached
node -ichild processes, outbound plain-HTTP requests on port 443 to paths like/0x/clsor/0x/ls, and rotate any credentials (npm publishing tokens, source repo access, CI secrets, cloud keys) that the affected host could reach.
On that last point, teams that haven't already deployed automated secret detection in CI may want to look at how that tooling has evolved — Pandromeda's coverage of GitHub's recent secret scanning upgrades is a useful starting point for understanding what modern detectors catch versus what still requires manual credential rotation after an incident like this one.
What's next
Sonatype's research team frames PolinRider as an active, evolving campaign rather than a single resolved incident — the wallet-based C2 resolution technique has now appeared across at least three separate waves of npm packages through 2026, with variations in encoding and which blockchain is used as the lookup layer. Given that pattern, more hijacked packages carrying a similar loader are a realistic possibility, and the specific wallet address and C2 IP disclosed in the November write-up should be treated as perishable indicators — useful today, but not something defenders should expect to remain valid indefinitely, precisely because the attacker can rotate the server behind the wallet at will. The most durable defense is the structural one: scrutinize what a dependency's code actually does at runtime, not just what it claims to do in its README, and don't assume a lack of install scripts means a lack of risk.
Frequently asked questions
What is PolinRider?
PolinRider is a malware loader campaign tracked by Sonatype Research Labs. It has appeared repeatedly across 2026 in hijacked and newly published npm packages, and Sonatype links it to the North Korea-linked Lazarus Group. Its defining trait is using a public blockchain (Tron in early 2026, Ethereum in later waves) as a lookup layer to find its command-and-control server.
Which npm packages were affected in the November 2026 wave?
Sonatype names 10 hijacked packages across 12 malicious releases: @adminide-stack/client-redux, @adminide-stack/health-api-server, @adminide-stack/user-activity-browser, @adminide-stack/utils (two versions), server-hemera-mongo (two versions), cdeops, @adminide-stack/forms-core, @adminide-stack/yantra-help-browser, @cdmbase/wiki-browser, and @pubngo-stack/help-browser. As of publication, Sonatype's write-up did not cite a corresponding GitHub Security Advisory ID for these specific releases.
How does the Ethereum wallet get used as a C2 address?
The loader queries public Ethereum RPC nodes (or a Blockscout API fallback) for the latest transaction sent from a specific wallet address. It reads the transaction recipient's address as raw bytes to decode a primary and secondary IPv4 address, then fetches its next-stage payload from that address. Because the operator can simply send a new transaction to point to a different server, they never need to publish a new npm package version to change infrastructure.
Does disabling npm install scripts protect against this attack?
No. Sonatype found no install or postinstall hooks in any of the 12 malicious releases. The loader is embedded in a file the package already executes during normal use, such as a bundled server entry point or a module the package's own code imports, so it runs on module load or app startup rather than during installation.
Is this confirmed to be the work of the Lazarus Group?
Sonatype's PolinRider resource page attributes the campaign to the Lazarus Group but notes that the label is often used broadly for North Korea-linked state activity rather than identifying specific individuals. In its technical write-ups on individual waves, Sonatype has at times described the PolinRider link itself as an assessment based on shared infrastructure (wallets, ports, request paths) rather than a fully confirmed, singular attribution.
What should developers do if one of the affected packages is in their dependency tree?
Check lockfiles for the specific flagged versions, remove and replace them with verified-clean releases, and don't assume a lockfile match alone proves or disproves execution. If there's any sign the loader ran — such as unexplained detached node processes or outbound HTTP requests to paths like /0x/cls or /0x/ls — treat the host as compromised and rotate reachable credentials, including npm, CI, and cloud secrets.
Sources
- Sonatype – How a Compromised npm Package Used Ethereum to Fetch Its Next Stage (PolinRider campaign page)sonatype.com
- Sonatype Research – PolinRider Loader Reappears in Hijacked npm Packagessonatype.com
- Sonatype – Hijacked npm Package Attempts to Deliver PolinRider-Linked RATsonatype.com
- Sonatype – Six npm Packages Use Ethereum Transactions to Retrieve Malicious Payloadssonatype.com
- Wikipedia – Lazarus Groupen.wikipedia.org
Felix Moreau writes Pandromeda's software coverage and how-to guides. He covers Windows, macOS and Linux updates, the apps people rely on, emulators and developer tools, and turns official documentation into clear, numbered steps that work on the current version.


