News and Notes from the Makers of Nexus | Sonatype Blog

Hijacked npm Package Attempts to Deliver PolinRider-Linked RAT

Written by Sonatype Security Research Team | May 21, 2026

Attackers do not need to wait for a CVE when they can publish directly into the build.

That is what Sonatype observed in two compromised versions of @common-stack/generate-plugin (CVSS 8.7), an npm package with more than 1,100 weekly downloads. Sonatype identified and flagged the compromised package versions after embedded code was found attempting to retrieve and execute a second-stage payload.

Sonatype believes these packages are associated with PolinRider, an Advanced Persistent Threat (APT) group linked with North Korea. If downloaded onto a developer machine, these malicious packages lead to full compromise and immediate action is needed.

What Happened

Sonatype researchers identified two malicious versions of @common-stack/generate-plugin — 9.0.2-alpha.21 and 9.0.2-alpha.22. The malicious code executes during installation, before the package ever needs to be executed. From there, it attempts to download and run a second-stage payload that contains remote access trojan, or RAT, functionality.

The malicious payload was appended to postcss.config.js, a file that was also commonly targeted during the earlier PolinRider campaign. postcss is a system used in many frameworks, including React,Vue, and Tailwind CSS build pipelines, which means it exists in packages across the ecosystem and is an ideal hiding spot. By appending malicious JavaScript to an otherwise ordinary configuration file, the attacker benefits from both camouflage and execution opportunity.

The package is almost identical to that earlier activity. It uses the same obfuscation technique, including the same decoder seed, rmcej%otb%, and attempts to pull down the final payload from the Tron blockchain instead of a traditional attacker-controlled server.

Using a blockchain transaction as part of the payload retrieval chain is a notable evasion technique. Instead of hard-coding a conventional command-and-control URL that can be taken down or blocked quickly, the attacker can use blockchain-hosted or blockchain-referenced data as a resilient pointer to the next stage. This can make the infrastructure harder to disrupt and harder for defenders to reason about during initial triage.

The overlap in file targeting, obfuscation, install-time execution, and payload retrieval behavior suggests deliberate reuse of established PolinRider techniques.

How Do Attackers Choose Hijack Targets?

Attackers know developers expect convenience utilities with their frameworks. That is exactly why they are useful.

The @common-stack/generate-plugin npm package is used in JavaScript/Node.js development workflows for plugin generation or scaffolding tasks — the kind of common boilerplate generation developer tooling that they often run with elevated trust during local development.

That makes compromise especially dangerous. Generator and scaffolding packages are expected to execute code as part of normal development workflows, giving attackers an opportunity to run malicious payloads inside trusted developer and build environments.

Compromising a package like this gives attackers access to developer and build environments that are often less guarded than more sandboxed application runtimes, with broader access to data, credentials, and propagation vectors. For an attacker, the build pipeline is not just a path to production. It is a credential-rich staging ground.

Why Developers Should Care

Install-time malware is especially dangerous because it can execute before the package is ever imported into an application.

That means developer laptops, build runners, CI/CD systems, and other package installation environments may be exposed simply by installing the compromised version. Once the second stage runs, removing the npm package does not necessarily remove the attacker’s access, persistence, or any credentials already collected.

A malicious dependency in production is bad. A malicious dependency in CI is worse. That is where the secrets live.

This is also why traditional vulnerability management workflows can lag behind the actual risk. There may be no CVE to wait for, no patch advisory to track, and no vulnerable function for developers to avoid calling. The compromise happens at intake, during installation, and the defensive window is measured in seconds.

What To Do If You Have Been Impacted

If your organization recently ran @common-stack/generate-plugin, treat affected systems as fully compromised and:

  1. Remove the affected package.

  2. Review and outbound network activity.

  3. Pause work on the code you ran this utility on.

  4. Assume the code it generated is compromised, and revert to a commit prior to running the utility.

  5. Rotate exposed developer, npm, GitHub, cloud, and CI/CD credentials.

  6. Investigate for second-stage payloads, persistence, or unusual process execution.

  7. Verify lockfiles and internal repositories are pinned to uncompromised versions.

  8. Block the malicious version across developer and build environments.

Removing the package is necessary, but it is not sufficient. Once a dropper runs, the real question is what it downloaded next.

Organizations should also verify that internal mirrors, artifact repositories, lockfiles, templates, and cached build images do not continue to reference or serve the compromised versions. A malicious version can remain reachable long after it disappears from day-to-day developer attention if it has already been cached internally.

The Bigger Pattern

This is another reminder that open source risk is no longer just about known vulnerabilities.

Attackers are increasingly targeting the places developers already trust: maintainers, publishing credentials, package registries, and install workflows. The package does not need to look suspicious if the account behind it is already trusted.

Open source is not the problem. Blind consumption is. Sonatype Firewall blocks malicious and suspicious packages before download, helping teams protect repositories, developer environments, and CI/CD pipelines.

Security teams need controls that can detect malicious behavior at intake, not only after a CVE is assigned. Developers do not need more dashboards. They need safer defaults.