PolinRider Campaign Keeps DPRK Malware in Compromised Developer’s npm Releases

Summary
An investigation found PolinRider malware in fetch-page-assets releases 1.2.9–1.2.14 and seven repositories belonging to a compromised developer, exposing gaps in npm’s response to compromised maintainers.
Key points
- The article attributes PolinRider to DPRK threat actors and reports 4,367 infected repositories across 2,152 owners.
- Malware was concealed in a VS Code task, a fake font file, and Babel configuration; the task can run on folder open, while the Babel payload can execute during tests or builds.
- The maintainer’s seven non-archived public repositories were reportedly force-pushed in coordinated bursts; the latest fetch-page-assets release, 1.2.14, contained both loaders.
- npm removed version 1.2.9 after a security advisory, but versions 1.2.10–1.2.14 remained available when the article was written.
- The investigation says the maintainer removed a visible payload but left the auto-execution trigger, and attackers later added another payload to a configuration file.
- The author recommends removing or pinning fetch-page-assets to version 1.2.8 or earlier, checking unfamiliar .vscode/tasks.json files for folder-open tasks, and investigating suspicious outbound activity.
Article Details
- Attack Vectors
- PolinRider injects obfuscated JavaScript into compromised developers’ repositories, including a VS Code task configured to run when a folder opens and a fake .woff2 font executed with Node.js.
- The attacker re-injected payloads account-wide through coordinated force-pushes to the victim’s repositories, then used release automation to publish infected npm package versions.
- A second loader was appended to babel.config.cjs, which the article says is loaded during npm test and npm run build, allowing execution in dependent projects without a person opening the repository in VS Code.
- The article assesses that the initial repository injection almost certainly came from a compromised dependency’s lifecycle script running during a CI job; it presents this as a likely explanation, not a confirmed cause.
- Defensive Notes
- If using fetch-page-assets, pin the dependency to version 1.2.8 or earlier, or remove it.
- Inspect .vscode/tasks.json files in projects for unexpected runOn: folderOpen tasks, especially tasks invoking non-code files.
- Treat a host as compromised if outbound logs show a Node.js process contacting 1rpc.io, eth.drpc.org, ethereum-rpc.publicnode.com, or blockscout.com, as the article advises.
- The article recommends reviewing a maintainer’s account and all associated repositories and packages after a malicious package version is found, notifying the maintainer directly, using pattern-based registry detection, and correlating repository findings with advisories.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| SHA1 | 0272b9f2b1a0dda93baebf3bae505e22959a5464 | Git blob identifier for the alternate malicious payload reported in html-to-gutenberg during the August burst. |
| SHA1 | 5e226620d2e360205cc8634e3c581a008d382561 | Git blob identifier for the malicious .vscode/tasks.json launcher found across the infected repositories. |
| SHA1 | 6df5b2c9c172d3b822494c3ef9083dbfc135ecf6 | Git blob identifier for the malicious fa-solid-400.woff2 payload from the July burst. |
| SHA256 | 9fbb31129c04e8eb1a50519fc864c74d1b20d57c07d4099348f8fbc9a1a1eae6 | SHA-256 of the malicious public/fonts/fa-solid-400.woff2 payload shipped in fetch-page-assets. |
| SHA256 | f5c6be4753d6613c97f1b10c4d93a5d97a8f4fb21eb13da0ed04b23a8a61c2f6 | SHA-256 of the malicious .vscode/tasks.json launcher reported in the infected repositories and package releases. |
MITRE ATT&CK
T1027 · Obfuscated Files or InformationThe article describes the JavaScript loaders as obfuscated and shows obfuscated code appended to babel.config.cjs.T1059.007 · JavaScriptObfuscated JavaScript loaders were executed with Node.js from the fake .woff2 file and the injected Babel configuration.T1078.004 · Cloud AccountsGitHub attributed coordinated force-pushes across the victim’s repositories to the victim’s account identity; the article says the operators may have possessed credentials or used an agent in the local environment.T1195.001 · Compromise Software Dependencies and Development ToolsThe article assesses that a compromised dependency’s lifecycle script likely wrote the initial malicious files during the maintainer’s CI job.T1195.002 · Compromise Software Supply ChainThe campaign used compromised maintainer repositories and npm releases to deliver malicious package versions to downstream projects.
People
Malware
Vendors
GitHubin Westeros. I think of this a lot when I watch North Korean threat actors compromising legitimate GitHub users to take control of their accounts. In the Game of Thrones universe, the army was truly dead, andnpmof compromised, legitimate GitHub users. And unsurprisingly, these victims also maintain or contribute to npm packages. DPRK is now weaponizing those accounts to deploy the latest, and best, DPRK malware into npm.
Products
fetch-page-assetsThis post is a case study of one such developer: DiogoAngelim, and their npm packages fetch-page-assets and html-to-gutenberg. It's a five-month story with one advisory, two visible cleanup attempts by the maintainer,GitHubin Westeros. I think of this a lot when I watch North Korean threat actors compromising legitimate GitHub users to take control of their accounts. In the Game of Thrones universe, the army was truly dead, andhtml-to-gutenbergis a case study of one such developer: DiogoAngelim, and their npm packages fetch-page-assets and html-to-gutenberg. It's a five-month story with one advisory, two visible cleanup attempts by the maintainer, and — asNode.jsdecade of sporadic real-world contributions. They provide useful packages, such as fetch-page-assets, a Node.js utility for extracting CSS, JavaScript, fonts, and images from a URL. It's the sort of tool a working webnpmof compromised, legitimate GitHub users. And unsurprisingly, these victims also maintain or contribute to npm packages. DPRK is now weaponizing those accounts to deploy the latest, and best, DPRK malware into npm.VS Code.vscode/tasks.json, a hidden VS Code task labeled “eslint-check,” set to "runOn": "folderOpen", whose actual command is node ./public/fonts/fa-solid-400.woff2.