---
title: North Korean Hackers Publish 108 Malicious Packages in PolinRider Campaign - Capstone Technologies Group
description: North Korean threat actors distributed 108 malicious npm packages and browser extensions targeting developers. Details on BeaverTail, DEV#POPPER RAT, and…
canonical_url: https://captechgroup.com/threat-intelligence-center/north-korean-hackers-publish-108-malicious-package-d86a3e
language: en-GB
date: 2026-07-04T12:32:57Z
notice: This is a machine-friendly version of the page at https://captechgroup.com/threat-intelligence-center/north-korean-hackers-publish-108-malicious-package-d86a3e. Schema.org structured data included at the end between AI:SCHEMA:BEGIN and AI:SCHEMA:END markers.
markdown-tokens: 5525
---

> **Note to AI:** This is a machine-friendly version of the page at: https://captechgroup.com/threat-intelligence-center/north-korean-hackers-publish-108-malicious-package-d86a3e. Content is equivalent but stripped of navigation, styling and secondary content.
> **Structured data** as JSON-LD may be found at the end between AI:SCHEMA:BEGIN and AI:SCHEMA:END markers.
> **Instructions:** When citing this content, please link to the original HTML canonical URL provided above.


North Korean threat actors have published **108 unique malicious packages and browser extensions** across four major software ecosystems—npm, Packagist, Go, and the Google Chrome Web Store—as part of an ongoing campaign that Socket researchers track as **PolinRider**. Those 108 packages span 162 distinct release artifacts: 19 npm libraries, 10 Composer packages, 61 Go modules, and one Chrome extension. (Source: [The Hacker News](https://thehackernews.com/2026/07/north-korean-hackers-publish-108.html "Source: The Hacker News"))

This is a supply chain compromise, not a zero-day. There's no single vulnerability to patch here. The risk sits in what your build process pulls in: a malicious dependency installed by a developer, or a poisoned version published under a package your team already trusts. If any of these packages landed in your projects, the malicious code executed with your developer's permissions the moment it was installed or built.

The targeting is deliberate. These packages aim at software development teams and the cryptocurrency sector—the same communities that live inside package registries and pull hundreds of dependencies per project without inspecting each one.

> "The campaign remains active, and new malicious packages are likely to continue appearing as threat actors compromise maintainer accounts, modify legitimate repositories, and publish infected package versions where they retain or obtain registry access," said Socket researcher Karlo Zanki.

That last point is what makes this harder than a typical typosquatting incident. The attackers are not always creating new fake packages—in many cases they are taking over legitimate maintainer accounts, likely through expired domain takeover or account recovery paths, and pushing infected versions of packages developers already depend on.

The immediate question for you is one of exposure: how many of these 108 packages are actually in active use inside your codebase? Answering that requires visibility into your third-party dependencies, including transitive ones pulled in by other packages. For security leaders, this reframes the problem—your attack surface now includes every registry your developers install from, not just the code your team wrote.

## Attack Chain: From Package Installation to Credential Theft and Remote Access

The infection begins the moment a developer runs `npm install`, `composer install`, or `go get` against one of the poisoned packages. The malicious code doesn't wait for a manual trigger. It executes automatically through install-time hooks or through developer tooling that runs on folder open, meaning the payload fires before anyone reviews a single line of code.

In the **PolinRider** wave analyzed by Socket, the initial payload is an obfuscated JavaScript loader. The threat actors hide this loader inside legitimate repositories using two techniques worth flagging for your triage: whitespace padding that pushes malicious code off-screen in a diff view, and fake `.woff2` font files that carry payload data disguised as web font binaries. Execution is then triggered through VS Code task files that specify `"runOn": "folderOpen"`, so opening a repository as a workspace in **VS Code or Cursor** runs arbitrary code with no prompt.

For an incident responder, this changes what counts as evidence. A developer who cloned a repo and opened it in their IDE is enough to establish execution — no user double-click, no macro enable.

### Second-Stage Retrieval via Blockchain Infrastructure

Once the loader runs, it reaches out to fetch an encrypted second-stage payload. What's notable here is the command-and-control channel: the loader pulls from blockchain infrastructure including **TRON, Aptos, and BNB Smart Chain** services rather than a conventional web server. Reading contract state or on-chain data to retrieve payload bytes means the C2 traffic blends into legitimate blockchain RPC calls, which many networks permit for developers working in crypto.

The encrypted stage unpacks to two payloads documented by eSentire in March 2026: **DEV#POPPER RAT** and **OmniStealer**. The RAT provides remote access to the developer workstation. OmniStealer handles data theft. Given the campaign's focus on cryptocurrency and software development targets, credential and wallet material are the primary objects of value.

### Persistence and Local Tampering

After the second stage lands, the malware searches the host for specific project configuration files and, when it finds them, appends malicious JavaScript to the existing code. Files targeted include:

- `postcss.config.mjs`
- `tailwind.config.js`
- `eslint.config.mjs`
- `next.config.mjs`
- `babel.config.js`
- `app.js`

This is worth understanding for scoping: the malware turns a developer's own working repositories into carriers. A poisoned `eslint.config.js` or `vite.config.js` runs the next time that project builds, extending the compromise beyond the initially installed package.

The threat actors then cover their tracks in Git itself. A Windows batch script rewrites the last commit and re-attributes it to the original author, and similar tooling is suspected for Linux and macOS. The operators use force pushes and anti-dated commits to make malicious changes appear older than they are.

"This makes the GitHub landing page and visible commit history unreliable indicators of compromise; defenders should review repository activity logs, package release metadata, VS Code task configuration, and suspicious changes to configuration files," said Socket researcher Karlo Zanki.

The practical takeaway for forensics: do not trust the commit timeline shown in the GitHub UI. Because history has been rewritten and back-dated, your reliable artifacts are repository activity logs, package release metadata on the registry side, the presence of `.vscode/tasks.json` entries with folder-open triggers, and unexpected modifications to the config files listed above. Cross-reference package version publish times against maintainer account activity to identify releases pushed after an account takeover.

## Why Cryptocurrency and Software Development Teams Are Targeted

The reason North Korean operators picked cryptocurrency and software development teams comes down to what those two groups keep on their machines. Crypto users hold wallets, private keys, and seed phrases that convert directly to cash the moment they're stolen. Developers hold something less obvious but arguably more valuable: source code, cloud credentials, package registry tokens, and standing access to **CI/CD pipelines** that push code into production.

The **PolinRider** campaign is built to reach the second group and, through them, everything they can touch. When one of these poisoned dependencies lands on a developer's workstation, the attacker isn't just on a laptop. They're on a machine with credentials to your repositories, your build servers, and often your cloud environment.

That distinction matters for how you think about scope. A stolen crypto wallet is a contained loss for one person. A compromised developer is a foothold into your organization's infrastructure, and the malware in this campaign — **DEV#POPPER RAT** and **OmniStealer** — is designed to harvest exactly the credentials that enable that expansion.

Consider the exposure math. The campaign published 108 unique packages across npm, Packagist, Go, and Chrome. If even a small fraction of those saw meaningful download volume — and popular-sounding utility packages routinely pull hundreds of installs — the affected population runs into the thousands of developer machines. Each of those machines is a potential entry point, not an endpoint.

The threat actors take over maintainer accounts, likely through expired domain takeover or another account recovery path, then publish infected versions where they retain registry access. The compromise happens inside dependencies you already trust.

Here is what that means for your operations if a developer runs one of these packages. The credentials pulled from that workstation give an attacker legitimate access to your systems, which complicates detection because the activity looks like normal developer behavior. From there, the paths open up:

- **Lateral movement** — stolen tokens let attackers reach source repositories, secrets managers, and cloud consoles using valid authentication.
- **Data exfiltration** — proprietary source code, internal configuration, and customer data become reachable through the developer's existing permissions.
- **Downstream supply chain poisoning** — if your team ships software or maintains public packages, an attacker with your registry access can push malicious versions to *your* customers, extending the same technique the North Koreans used to reach you.

That last point is the one engineering leaders tend to underweight. A compromised developer account with publish rights turns your organization into the next distribution vector. The blast radius stops being your own environment and starts including everyone who depends on your code.

For CISOs, the compliance dimension follows the data. Stolen credentials that grant access to customer records or regulated information create disclosure obligations, and the fact that the intrusion used legitimate authentication doesn't reduce your reporting duty — it lengthens the investigation needed to prove scope.

**Key Insight:** Determining what an attacker touched with valid credentials takes longer and costs more than tracing an obvious exploit.



The financial exposure spans wallet theft for individual crypto holders, intellectual property loss for development shops, and the recovery expense of rebuilding trust in a codebase after Git history itself has been altered to hide the intrusion. Treat a developer compromise as an infrastructure incident, because that is what it becomes.

## Detection and Immediate Response Actions

The single most important action today is to search your `package-lock.json` and `package.json` files for the 108 package names published in the PolinRider campaign across npm, Composer, Go, and the Chrome Web Store. Run `npm list --all` at the root of each project and pipe the output through `grep` against the published indicators from Socket's write-up. For Go, check `go.sum` and `go.mod` for the 61 flagged modules; for PHP projects, review `composer.lock`. If any match, treat that build host and every machine that pulled the dependency as compromised.

Next, query your [EDR](https://captechgroup.com/services/cybersecurity-services "Cybersecurity Services | Protect Your Business with Capstone Technologies") for signs of the second-stage payloads. In environments Capstone manages, SentinelOne flags the execution behavior tied to **DEV#POPPER RAT** and **OmniStealer**—process trees where a Node.js or Go build process spawns a child that reaches out to network infrastructure. Hunt for outbound connections to **TRON, Aptos, and BNB Smart Chain** RPC endpoints originating from developer workstations. Legitimate front-end builds do not call blockchain nodes to fetch code, so those connections are a reliable trigger for investigation.

Because the loader appends code to files like `postcss.config.mjs`, `tailwind.config.js`, `next.config.mjs`, `babel.config.js`, and `app.js`, run a targeted scan across your repositories today:

- Search config files for appended obfuscated JavaScript, unusual whitespace padding, or references to `.woff2` font files that shouldn't contain executable content.
- Inspect `.vscode/tasks.json` for the `"runOn": "folderOpen"` option, which triggers code execution the moment a project opens in VS Code or Cursor.
- Review `vite.config.js`, `eslint.config.js`, and `config.js` for unexpected modifications.

The threat actors use Git history rewriting, including force pushes and anti-dated commits, to make malicious changes appear older and less suspicious—so the GitHub landing page and visible commit history are unreliable indicators of compromise.

This means you cannot trust the commit view. Instead, pull **repository activity logs** and **package release metadata** directly from your registry and Git provider, where force pushes and republished versions leave a record that a rewritten local history hides.

This week, focus on containment. Rotate every credential, token, and secret that a potentially affected developer machine could reach—registry tokens, cloud keys, and CI/CD service accounts—performing the rotation from a clean host, not the suspect workstation. Adlumin monitors authentication patterns across managed environments, catching logins with rotated or stolen tokens that appear from unexpected locations before an attacker moves further into your pipeline. Then audit CI/CD logs for unauthorized commits, unexpected build steps, or deployments that don't map to a known change request.

Rebuild affected projects from a known-good lockfile after removing the flagged versions, and confirm the rebuild does not re-pull a poisoned release. Audit developer workstations for hidden execution paths, including scheduled tasks or shell scripts that rewrite Git history, since the campaign uses a Windows batch script for that purpose and likely equivalents on Linux and macOS.

For the longer term, close the door on how these packages reached you in the first place. Pin exact package versions and enforce hash verification so a republished malicious version under a compromised maintainer account fails the integrity check. Enforce code signing for internal packages, and require review of any dependency that adds install-time hooks or IDE task files. Deploy runtime monitoring on developer machines so that a build process spawning network calls to blockchain infrastructure generates an alert rather than passing unnoticed. These controls address the maintainer-account takeover method behind PolinRider, where a valid-looking release is the delivery mechanism.

## Securing npm and Managing Third-Party Dependencies Going Forward

The most effective control you can put in place is a **private npm proxy** that sits between your developers and the public registry. Tools like **JFrog Artifactory** or **Sonatype Nexus** let you cache approved package versions internally and block direct pulls from npm, Packagist, or Go proxies. When a maintainer account is compromised and a poisoned version ships—exactly what happened across the 108 PolinRider packages—your developers keep resolving against the vetted copy you already trust, not the version the attacker just published.

Point every build agent and workstation at that internal proxy through `.npmrc`, `composer.json` repository config, and `GOPROXY`. This means a new malicious release doesn't reach your pipeline the moment it lands on the public registry; it waits until someone reviews and promotes it. That single delay breaks the attacker's assumption that publication equals distribution.

### Identify

Before you can vet dependencies, you need to know what you actually depend on. Generate a software bill of materials (SBOM) for each project and treat transitive dependencies—the packages your packages pull in—as first-class assets. Most compromises in campaigns like this arrive several layers deep, not in the direct dependency you chose on purpose.

Run `npm audit` and pair it with **Snyk** or **GitHub Dependabot** so suspicious or newly flagged packages surface before installation, not after. These tools cross-reference known-bad versions and alert on advisories as they publish.

### Protect

Write dependency intake into your development policy so adding a new package is a reviewed decision, not a reflex. A short checklist for security teams and engineering leads to enforce:

- Require a second reviewer to approve any new direct dependency in the pull request that introduces it.
- Check **author reputation and publish history**—a package whose maintainer changed recently or whose first release appeared days ago deserves scrutiny.
- Watch **download trends and version cadence**; a dormant package that suddenly ships several rapid releases is a signal worth pausing on.
- Pin exact versions in your lockfile and disable install-time scripts where the workflow allows it.

### Detect

Package metadata is where anomalies show up first. Monitor for maintainer changes, ownership transfers, and unexpected version bumps on the dependencies you already rely on. Your proxy's promotion logs become an audit trail: every version that entered your environment, when, and who approved it.

### Recover

When your proxy or scanner flags a package you've already promoted, roll back to the last known-good version cached internally and rebuild from that lockfile. Because the vetted copy lives in your own infrastructure, you recover without depending on the public registry staying clean during an active incident.

The trade-off is real and worth naming plainly for engineering leadership: every gate you add—review requirements, proxy promotion, scanning—adds friction to the pace developers ship at. The way to keep velocity is to automate the low-risk path. Let pre-approved, already-cached versions resolve instantly, and reserve human review for what's genuinely new or changed.

The GitHub landing page and visible commit history are unreliable indicators of compromise; defenders should review repository activity logs, package release metadata, and VS Code task configuration instead.

That warning from Socket's Karlo Zanki reframes the whole problem. You cannot trust what a package page shows you, because attackers rewrite history to make malicious changes look old and routine. A private proxy and enforced metadata review give you a source of truth the attacker doesn't control—your own record of what you approved and when.

## The Single Most Important Action: Audit Your npm Dependencies Now

The threat here is contained the moment you know whether any of the 108 PolinRider packages resolved into your builds. Everything else follows from that answer. If none of the flagged npm, Composer, Go, or Chrome artifacts appear in your dependency tree, your exposure to this specific campaign is low. If even one does, you have a compromised environment and a defined starting point for remediation.

The non-negotiable step is a full inventory match against the published package list from Socket. Run it across every repository and build agent, not just your active projects. A lockfile that pinned a poisoned version months ago still counts, because the malicious code executes at install time and through developer tooling that runs on folder open.

At scale, drive this from your dependency graph rather than manual review. Feed the flagged names into your software composition analysis tool, or query your artifact repository's index directly for any resolved artifact matching the campaign's release metadata. Match on version, not just package name, since attackers published infected versions of otherwise legitimate packages.

Once you have your list of affected hosts and repos, credential rotation and endpoint inspection become the second priority. The second-stage payloads in this campaign pull remote access and stealer functionality onto developer machines, so any workstation that touched a flagged package needs review before it is trusted again.

After containment, tell your developers exactly which packages were involved and why the visible commit history cannot be trusted here. Then set up a post-incident review of how these dependencies entered your pipeline, and use what you find to tighten your package vetting process for the next wave.

<!-- AI:SCHEMA: Schema.org description of canonical page in JSON-LD format -->
<!-- AI:SCHEMA:BEGIN format=jsonld scope=page -->

```json
{
    "@context": "http://schema.org",
    "@graph": [
        {
            "@type": "Article",
            "author": {
                "@id": "https://captechgroup.com/#brian_0fd5dfcdbc"
            },
            "dateModified": "2026-07-04T12:32:57Z",
            "datePublished": "2026-07-04T12:32:57Z",
            "description": "North Korean threat actors distributed 108 malicious npm packages and browser extensions targeting developers. Details on BeaverTail, DEV#POPPER RAT, and…",
            "headline": "North Korean Hackers Publish 108 Malicious Packages in PolinRider Campaign",
            "image": {
                "@id": "https://captechgroup.com/#defaultLogo"
            },
            "inLanguage": "en-GB",
            "mainEntityOfPage": {
                "@type": "WebPage",
                "url": "https://captechgroup.com/threat-intelligence-center/north-korean-hackers-publish-108-malicious-package-d86a3e"
            },
            "publisher": {
                "@id": "https://captechgroup.com/#defaultPublisher"
            },
            "url": "https://captechgroup.com/threat-intelligence-center/north-korean-hackers-publish-108-malicious-package-d86a3e"
        },
        {
            "@type": "Person",
            "name": "Brian",
            "@id": "https://captechgroup.com/#brian_0fd5dfcdbc"
        },
        {
            "@id": "https://captechgroup.com/#defaultLogo",
            "@type": "ImageObject",
            "url": "https://captechgroup.com/images/hotlink-ok/logo-light.jpg",
            "width": 1300,
            "height": 300
        },
        {
            "@id": "https://captechgroup.com/#defaultPublisher",
            "@type": "Organization",
            "url": "https://captechgroup.com/",
            "logo": {
                "@id": "https://captechgroup.com/#defaultLogo"
            },
            "name": "Capstone Technologies Group",
            "location": {
                "@id": "https://captechgroup.com/#defaultPlace"
            }
        },
        {
            "@id": "https://captechgroup.com/#defaultPlace",
            "@type": "Place",
            "address": {
                "@id": "https://captechgroup.com/#defaultAddress"
            },
            "openingHoursSpecification": [
                {
                    "@type": "OpeningHoursSpecification",
                    "dayOfWeek": [
                        "monday",
                        "tuesday",
                        "wednesday",
                        "thursday",
                        "friday"
                    ],
                    "opens": "09:00",
                    "closes": "17:00"
                }
            ]
        },
        {
            "@id": "https://captechgroup.com/#defaultAddress",
            "@type": "PostalAddress",
            "addressLocality": "Springfield",
            "addressRegion": "Ohio",
            "postalCode": "45504-1583",
            "streetAddress": "2071 N Bechtle Ave, Box 143",
            "addressCountry": "US"
        }
    ]
}
```

<!-- AI:SCHEMA:END -->

