Skip to content

Lazarus-linked Rollup polyfill npm malware

Tags

Summary

JFrog Security Research reported a Lazarus-linked npm malware cluster that masqueraded as Rollup polyfill tooling rather than using an obvious typo. The entry packages rollup-packages-polyfill-core and rollup-runtime-polyfill-core copied the README, repository metadata, homepage, package shape, and plausible plugin code from the legitimate rollup-plugin-polyfill-node ecosystem, then appended hidden import-time logic that installed second-stage packages.

JFrog observed six npm packages in the cluster: rollup-packages-polyfill-core, rollup-runtime-polyfill-core, swift-parse-stream, quirky-token, react-icon-svgs, and rollup-plugin-polyfill-connect. At publication time, JFrog said rollup-plugin-polyfill-connect and react-icon-svgs had received npm security-holding versions while the other four malicious packages were still live. The campaign is durable for defenders because it combines package masquerading, layered npm dependency installation, JSONKeeper staging, browser/wallet theft, and operator interactive access against developer workstations.

Public reporting

  • 2026-06-30: JFrog published analysis of the cluster and linked its tradecraft to previous North Korean / Lazarus npm campaigns based on the layered package structure, legitimate-looking metadata, hidden execution, environment checks, and credential-theft / remote-access payloads.
  • The legitimate rollup-plugin-polyfill-node package had roughly 295,000 weekly downloads and more than 1.2 million monthly downloads in JFrog's cited npm ecosystem context, making the naming space plausible during dependency review.
  • The two Rollup-themed entry packages install second-stage packages at import time: rollup-packages-polyfill-core installs swift-parse-stream, and rollup-runtime-polyfill-core installs quirky-token.
  • The second-stage packages are near-identical SVG utilities that fetch a JSON object from JSONKeeper and evaluate the model field. JFrog observed the same staging pattern with react-icon-svgs, which installed rollup-plugin-polyfill-connect as a second stage.

Execution chain

  1. A developer or build environment installs one of the Rollup-looking entry packages, or another package path that pulls the same cluster.
  2. The package exposes functional-looking Rollup/polyfill code, but the CommonJS dist/index.js path contains appended malicious logic. JFrog noted that the ESM dist/es/index.js files did not contain the appended install-and-load routine in the analyzed samples.
  3. The import-time routine decodes and runs npm install commands such as npm install swift-parse-stream --no-save --silent --no-audit --no-fund or npm install quirky-token --no-save --silent --no-audit --no-fund.
  4. The second-stage package retrieves JSONKeeper-hosted content and evaluates the model field, which leads to further Node.js payloads.
  5. The malware installs runtime dependencies such as axios, socket.io-client, ssh2, node-pty, sharp, screenshot-desktop, clipboardy, and @nut-tree-fork/nut-js, depending on component and platform.
  6. The remote-access component profiles the host, checks for VM markers, supports command execution, interactive terminal sessions, SSH sessions, terminal resize/input forwarding, and on Windows can perform screenshot, clipboard, mouse, keyboard, and hotkey operations.
  7. The data-theft component targets browser profile databases and extension storage for Chrome, Edge, Brave, Opera, LT Browser, and common cryptocurrency wallets, with macOS keychain collection also attempted.

Indicators and pivots

Package names

  • rollup-packages-polyfill-core
  • rollup-runtime-polyfill-core
  • swift-parse-stream
  • quirky-token
  • react-icon-svgs
  • rollup-plugin-polyfill-connect

Network indicators reported by JFrog

  • hxxps://www.jsonkeeper.com/b/3P9BF
  • hxxp://216.126.236.244/api/service/98cb54c0b4ac259d30c9c1ca1ae87c68
  • hxxp://216.126.236.244/api/service/makelog
  • hxxp://216.126.236.244/api/service/process/
  • hxxp://216.126.236.244:4801
  • hxxp://216.126.236.244:4806/upload
  • hxxp://216.126.236.244:4809/upload
  • hxxp://216.126.236.244:4809/cldbs

Host and behavior pivots

  • Temporary files or markers named scdata, ldata, vhost.ctl, node pack, node scdata, and node ldata under temporary paths.
  • Import-time npm execution with flags such as --no-save, --silent, --no-audit, --no-fund, --no-warnings, --no-progress, and --loglevel silent.
  • Unexpected installation of socket.io-client, ssh2, node-pty, sharp, screenshot-desktop, clipboardy, or @nut-tree-fork/nut-js from packages that should only provide Rollup polyfill or SVG utility functionality.
  • Access to browser credential stores such as Login Data, Login Data For Account, Web Data, Local Extension Settings/<extension-id>/*, and on macOS ~/Library/Keychains/login.keychain-db.
  • Use of pbpaste or PowerShell clipboard / disk-enumeration commands from Node.js package lifecycle or import-time contexts.

Defender takeaways

  • Treat package names that are plausible-but-not-identical to popular build tooling as suspicious, especially when they copy README and repository metadata from a legitimate project.
  • Review both CommonJS and ESM entry points. JFrog's samples hid the malicious routine in the CommonJS path while leaving the ESM path clean-looking.
  • Block or alert on npm execution spawned from package import paths, not only lifecycle scripts. This campaign used hidden import-time installation.
  • In CI and developer endpoints, hunt for the six package names, the JSONKeeper URL, 216.126.236.244, and silent npm installs that add remote-access libraries to unrelated packages.
  • If exposure is suspected, preserve npm cache, lockfiles, package tarballs, shell history, EDR process trees, browser profile access telemetry, and outbound proxy/DNS logs before cleanup. Rotate browser, source-control, package-registry, cloud, SSH, and wallet-related secrets from a clean host.

Sources

  • JFrog Security Research: https://research.jfrog.com/post/rollup-polyfill-masquerading/