
PolinRider Jumps the Fence to Go, Packagist, npm, PyPI
OpenSourceMalware documents how PolinRider, a DPRK/Lazarus Group supply-chain campaign tied to the Contagious Interview cluster, spread from GitHub account takeovers into Go modules, Packagist/Composer packages, npm libraries and Chrome extensions without any change to the malware itself. Because Go and Packagist resolve packages directly from git tags rather than a separately-uploaded artifact, a compromised GitHub account automatically becomes a compromised registry release — unlike npm/PyPI, which require a separate publishing credential and largely stalled the takeover at the registry boundary. The post gives ecosystem-by-ecosystem evidence (10 Packagist packages, 80+ Go modules, an NPM/Chrome cluster), IOCs (TRON/Aptos dead-drop addresses, XOR keys, loader signatures, temp_auto_push.bat), a campaign timeline, and remediation guidance for Go/Composer maintainers.
What it is
PolinRider, a DPRK-linked supply-chain campaign (Lazarus Group / Contagious Interview cluster) that takes over legitimate GitHub accounts and injects an obfuscated JavaScript loader into repos the maintainer already owns. Originally a GitHub-only problem (675 repos in the first report, then 1,951 repos across 1,047 owners), it has now surfaced in package registries: ~200 malicious release artifacts across 111 packages/extensions — 80+ Go modules, 10 Packagist packages, an NPM cluster, and a couple of Chrome extensions.
How it works — why the jump was "free"
The page's core actionable insight is a distinction between two resolution models:
- Model A (npm, PyPI): the registry hosts its own artifact (tarball/wheel), uploaded with a separate publishing token. Install pulls the registry's copy, not GitHub. The registry credential is a different key from the GitHub credential.
- Model B (Go, Packagist): the registry resolves directly from the git repo. Go — a version is just a git tag;
go get ...@v1.4.0makes proxy.golang.org fetch that commit. No publish token exists. Packagist — a GitHub webhook makes Packagist re-read the repo on push;composer requiredownloads a zipball of the tagged commit straight from GitHub.
In Model B, repository write access is publishing access. The GitHub takeover the campaign already had at scale automatically compromised every backing Go module and Composer package — no stolen npm/PyPI token needed.
flowchart TD
A[GitHub account takeover + malicious commit] --> B{Resolution model?}
B -->|Model A: npm, PyPI| C[Needs separate publish token<br/>— NOT auto-compromised]
B -->|Model B: Go, Packagist| D[Repo IS the artifact<br/>— auto-published on push/tag]The injection technique (JS-in-PHP)
DPRK uses VS Code to run JavaScript payloads regardless of the host repo's language. The actor force-pushes two new directories: a VS Code config dir (extension.json, launch.json, spellright.dict, tasks.json — payload usually in tasks.json), and a public/fonts folder where one or more fake .woff2 fonts is actually malicious JS. Example: 7span/react-list had the loader appended to vite.config.js via force-push (commit 1c1d61b). Payloads use blockchain dead-drops to fetch the Lazarus stealer toolkit; a Windows script rewrites git history to disguise the commit.
What to do
Check for and purge these 10 confirmed compromised Packagist packages:
thiio/kubernetes-php-sdk
arsl/optima-class
olc/olc-php
sevenspan/laravel-whatsapp
adxio/twig-hmvc
sevenspan/code-generator
lambda-platform/moqup
roberts/leads
sevenspan/laravel-chat
plusinfolab/logstationBecause Go/Packagist pull from tags, treat any Go module or Composer dependency as trusted only as far as its backing GitHub repo — version-pinning to a tag does not protect you if the tag was force-pushed. Look for unexpected .vscode/tasks.json, fake font files under public/fonts, and JS appended to config files.
Caveats
Go module counts (80+) and package names are enumerated only for Packagist; the specific NPM libraries and Chrome extensions are referenced but not named in the fetched text. The page cuts off mid-walkthrough ("If you look at line 16").
Technologies named here
- GitHub
- OpenSourceMalware.com
- Socket
- Go modules
- Packagist / Composer
- proxy.golang.org
- Composer
- npm
- PyPI
- Chrome extensions
- VS Code
- 7span/react-list
- Go
- Packagist
- Chrome
Techniques named here
- GitHub account takeover for supply-chain compromise
- Obfuscated JavaScript appended to config files
- VS Code tasks.json trigger
- Fake .woff2 font files hiding JavaScript
- Malicious npm dependency postinstall hooks
- Git history rewriting / anti-dated force push
- Blockchain dead drop C2
- Domain-takeover-based account recovery abuse
Threat actors named here
- PolinRider
- Lazarus Group / Contagious Interview
- TasksJacker
- BeaverTail
- InvisibleFerret
- DPRK
- Lazarus Group
- Contagious Interview
- OmniStealer
- DEV#POPPER
Related in Threat Intel
Reverse Engineering the Six Stages of MacSync Stealer and RAT
AI-Coded Malware | Analyzing Vibe-Coded AD Enumeration | Huntress
