PolinRider: DPRK Supply-Chain Campaign Hides BeaverTail/InvisibleFerret Malware in JS Build Config Files (tailwind.config.js et al.)
PolinRider: DPRK Supply-Chain Campaign Hides (TL-2026-1143), also tracked as Operation PolinRider, is a critical-severity supply-chain compromise, first published 2026-06-21. It is attributed to PolinRider (North Korea) with high confidence, affects npm tailwindcss-style-animate, maps to 38 MITRE ATT&CK techniques (T1005, T1027, T1027.013), and is covered by 9 detection rules and 53 indicators of compromise.
Key facts for TL-2026-1143
- Threat ID
- TL-2026-1143
- Also known as
- Operation PolinRider
- Severity
- CRITICAL
- Status
- ACTIVE
- Category
- SUPPLY_CHAIN
- First published
- 2026-06-21
- Last reviewed
- 2026-06-21
- Attribution
- PolinRider
- Attribution confidence
- HIGH
- Nation-state nexus
- North Korea
- Motivation
- FINANCIAL
- Target sectors
- technology, software development, cryptocurrency, financial services, information technology services, government administration, defense industrial base
- Target regions
- Global, North America, South Asia, Europe
- Detection rules
- 9
- Indicators of compromise
- 53
Malware and tooling in PolinRider: DPRK Supply-Chain Campaign Hides
Malware and tooling: BeaverTail - S1246, DEV#POPPER, GolangGhost (OS X), InvisibleFerret - S1245, OmniStealer, PylangGhost, AnyDesk, Astrill VPN
A DPRK/Lazarus-aligned actor tracked as PolinRider compromises npm, Packagist, and Go module packages whose postinstall/build hooks append obfuscated JavaScript to common build config files (tailwind.config.js, postcss.config.mjs, eslint.config.mjs, next.config.mjs, babel.config.js, app.js), loading a BeaverTail stager and a cross-platform InvisibleFerret RAT that steal browser credentials, SSH keys, cloud/npm/GitHub tokens, and cryptocurrency wallets. As of 2026-04-11 the campaign had compromised 1,951 public GitHub repositories across 1,047 unique owners; a follow-on wave published 108 additional malicious packages/extensions across npm, Packagist, Go modules, and the Chrome Web Store as of 2026-07.
How PolinRider: DPRK Supply-Chain Campaign Hides works
PolinRider is a DPRK/Lazarus-aligned supply-chain operation, first flagged by the OpenSourceMalware (OSM) research team in March 2026, that merges the previously tracked 'TasksJacker' and 'Contagious Interview' activity clusters. The actor compromises legitimate npm, Packagist, and Go module packages (and, in the July 2026 wave, a Chrome Web Store extension) so that their install/build lifecycle silently appends obfuscated JavaScript to the end of widely-used JS/TS build configuration files — tailwind.config.js, postcss.config.mjs, eslint.config.mjs, next.config.mjs, babel.config.js, and app.js — after the file's legitimate content, so the payload executes automatically the next time any build tool (webpack, Vite, Next.js, PostCSS, ESLint) imports the module. A second delivery vector abuses `.vscode/tasks.json` with `"runOn": "folderOpen"` to gain code execution the moment a victim opens an infected repository folder in VS Code, and a third vector masquerades JavaScript payloads as binary `.woff2` font files.
Once triggered, the loader fingerprints the host OS, then reaches out to public blockchain RPC infrastructure (TRON, Aptos, and BNB Smart Chain — the 'EtherHiding'/blockchain dead-drop technique also seen elsewhere in DPRK tradecraft) to retrieve an encrypted second-stage payload, decrypts it with an embedded XOR key, and executes it via `eval()`. This delivers an updated variant of the BeaverTail JavaScript stager, which in turn downloads a Python interpreter and the InvisibleFerret cross-platform RAT (a three-component Python backdoor: downloader, main payload with fingerprinting/remote-control/keylogging/exfiltration, and a dedicated browser-credential stealer). Follow-on payloads observed in the campaign include the Node.js RAT DEV#POPPER (multi-operator command queues, socket.io-client C2, `/verify-human/[VERSION]` heartbeat and `/u/f` file-upload endpoints, Node.js module-search-order hijacking via a hidden `.node_modules` folder, and sandbox/CI evasion) and OmniStealer (browser data, session cookie, and cryptocurrency wallet exfiltration, also over socket.io-client).
The actor further obfuscates its footprint using a 'Glassworm' technique — invisible zero-width Unicode and Private-Use-Area characters embedded in source to hide encrypted bytecode from code review and diff tools — and a 'ForceMemo' technique that uses stolen GitHub tokens to rebase malicious commits into repository history with falsified author/committer dates, evading standard review. A destructive companion behavior observed on 2026-05-27 force-pushes a single collapsed commit across all branches of compromised repositories, destroying divergent branch history (recoverable only via the GitHub Events API within its ~48-hour retention window).
Campaign scale grew from 675 repositories / 352 owners (2026-03-08) to 1,951 repositories / 1,047 owners (2026-04-11), with a compromised GitHub account (Xpos587) and organization (7span/sevenspan) used to push malicious Go modules and Packagist packages, and a synchronized bulk-modification wave across the Xpos587 account on 2026-06-23 at 10:00 UTC. A subsequent, distinct wave publishing 108 new malicious packages/extensions (162 release artifacts: 19 npm libraries, 10 Packagist packages, 61 Go modules... and 80 Go modules per Socket's count, plus one Chrome extension) across npm, Packagist, Go modules, and the Chrome Web Store was reported 2026-07-06/07. PolinRider overlaps infrastructure, tooling (AnyDesk, Astrill VPN), and an operator email (hundredup2023@gmail.com) with the related PurpleBravo/PurpleDelta clusters, and is attributed with high confidence to DPRK state-sponsored actors tracked elsewhere as Lazarus Group, Famous Chollima, Void Dokkaebi, CL-STA-0240, and Tenacious Pungsan — part of the broader 'Contagious Interview' operation that also uses fake recruiter personas and weaponized take-home coding assessments to compromise individual developers directly.
MITRE ATT&CK techniques used in TL-2026-1143
Collection
T1005 Data from Local System; T1119 Automated Collection
Defense Evasion
T1027 Obfuscated Files or Information; T1027.013 Encrypted/Encoded File; T1036.008 Masquerade File Type; T1070 Indicator Removal; T1140 Deobfuscate/Decode Files or Information
Exfiltration
T1041 Exfiltration Over C2 Channel
Credential Access
T1056.001 Keylogging; T1552.001 Credentials In Files; T1552.004 Private Keys; T1555.003 Credentials from Web Browsers
Execution
T1059.006 Python; T1059.007 JavaScript; T1129 Shared Modules; T1204.002 Malicious File
Command and Control
T1071.001 Web Protocols; T1102.002 Bidirectional Communication; T1105 Ingress Tool Transfer; T1573.001 Symmetric Cryptography
Discovery
T1082 System Information Discovery; T1083 File and Directory Discovery; T1087 Account Discovery; T1518 Software Discovery
Privilege Escalation
T1134.001 Token Impersonation/Theft
Initial Access
T1195 Supply Chain Compromise; T1195.001 Compromise Software Dependencies and Development Tools; T1195.002 Compromise Software Supply Chain; T1566.002 Spearphishing Link; T1566.003 Spearphishing via Service
Persistence
T1547.001 Registry Run Keys / Startup Folder; T1554 Compromise Host Software Binary
Impact
T1565.001 Stored Data Manipulation
Resource Development
T1583.001 Domains; T1585.001 Social Media Accounts; T1587.001 Malware; T1588.002 Tool; T1608.001 Upload Malware
Affected products and versions in PolinRider: DPRK Supply-Chain Campaign Hides
- npm — tailwindcss-style-animate
Vulnerable versions: 1.1.6 and re-published malicious versions
Fixed in: package removed/scrubbed from registry - npm — tailwind-mainanimation
Vulnerable versions: all published malicious versions
Fixed in: removed by npm - npm — tailwind-autoanimation
Vulnerable versions: all published malicious versions injecting payload into src/index.js
Fixed in: N/A - npm — @aifabrix/miso-client
Vulnerable versions: malicious versions
Fixed in: N/A - npm — @iflow-mcp/watercrawl-watercrawl-mcp
Vulnerable versions: malicious versions
Fixed in: N/A - npm — @usebioerhold8733/s-format
Vulnerable versions: 4 incrementally-staged malicious versions published within a 48-hour window
Fixed in: N/A - Go Modules (proxy.golang.org) — Xpos587/git2md
Vulnerable versions: v0.0.0-20260503100027-79bdb26ca95d and related pseudo-versions
Fixed in: N/A - Go Modules — Xpos587/markfetch
Vulnerable versions: malicious versions
Fixed in: N/A - Go Modules — Artiffusion-Inc/mirofish
Vulnerable versions: malicious versions
Fixed in: N/A - Packagist (Composer) — 7span/react-list (sevenspan namespace, 10 packages)
Vulnerable versions: malicious versions
Fixed in: N/A
Remediation for PolinRider: DPRK Supply-Chain Campaign Hides
Patches
- No vendor patch applies — this is a malicious-package/supply-chain compromise, not a software vulnerability. Remediation is removal of the compromised package versions, credential rotation, and repository history restoration
Immediate actions
- Audit all Node.js/JS/TS projects for unexpected appended code at the end of tailwind.config.js, postcss.config.mjs, eslint.config.mjs, next.config.mjs, babel.config.js, and app.js
- Run `npm ci`/`npm install` with `--ignore-scripts` on untrusted or newly-cloned repositories to block malicious postinstall hook execution
- Inspect `.vscode/tasks.json` for `"runOn": "folderOpen"` entries and remove or disable auto-executing tasks; enable VS Code workspace-trust prompts
- Scan for masqueraded binary/font files (e.g., `.woff2` files whose MIME/content is JavaScript/text rather than valid font magic bytes) and for zero-width/Private-Use-Area Unicode characters hiding encoded payloads in source
- Revoke and rotate all GitHub personal access tokens, SSH keys, npm tokens, and cloud (AWS/GCP) credentials on any developer machine that touched a suspect repository or package
- Audit GitHub Events API history for unexpected force-pushes and restore branches from pre-attack commit SHAs within the ~48-hour Events API retention window
- Block outbound traffic to known BeaverTail/InvisibleFerret C2 IPs and non-standard ports (1224, 1244, 1245, 3000), and alert on outbound connections from developer/build hosts to TRON/Aptos/BNB Smart Chain RPC endpoints
Workarounds
- Manually diff build configuration files against known-good upstream versions before every build until automated integrity tooling is deployed
- Set `ignore-scripts=true` in `.npmrc` organization-wide to disable npm lifecycle script execution by default
Longer-term hardening
- Deploy EDR/behavioral detection able to flag Node.js processes spawning Python interpreters, unexpected `eval()` of network-fetched data, or blockchain RPC calls from build/CI hosts
- Enforce `task.allowAutomaticTasks` = off and require workspace-trust confirmation for all IDE task execution org-wide
- Adopt dependency pinning, lockfile hash verification, and a vetted internal registry/proxy mirror for npm, Packagist, and Go modules
- Build and test third-party or externally-contributed code inside ephemeral, credential-isolated Dev Containers with no forwarded SSH/GitHub/cloud credentials
- Implement mandatory code review, signed commits, and force-push restrictions/branch protection on all organization repositories
- Train hiring managers and engineers on DPRK fake-recruiter social engineering and weaponized take-home coding-assessment lures ('Contagious Interview')
Weaknesses (CWE) in PolinRider: DPRK Supply-Chain Campaign Hides
CWE-506, CWE-829, CWE-494, CWE-1357
Timeline of PolinRider: DPRK Supply-Chain Campaign Hides
- The 'Contagious Interview' DPRK campaign (CL-STA-0240), the direct predecessor cluster to PolinRider, is first publicly reported using fake recruiter lures to deliver BeaverTail and InvisibleFerret to job-seeking developers.
- BeaverTail is rewritten from pure JavaScript into the Qt framework, gaining cross-platform Windows (MSI) and macOS (DMG) installer compilation while masquerading as legitimate video-conferencing apps (MiroTalk, FreeConference).
- The PolinRider campaign begins operating, using compromised GitHub repositories injected with JavaScript loaders that lead to DEV#POPPER and OmniStealer payloads.
- The OpenSourceMalware (OSM) research team first flags PolinRider, at which point 675 public GitHub repositories belonging to 352 unique owners are confirmed compromised with obfuscated JavaScript payloads implanting a new BeaverTail variant.
- Compromise scale grows 2.9x to 1,951 public GitHub repositories across 1,047 unique owners; OSM completes end-to-end reverse engineering of the full attack chain including the Windows-side InvisibleFerret module delivered from a blockchain dead-drop after the BeaverTail loader stage.
- A mass force-push incident collapses divergent branch histories across hundreds of developer repositories tied to compromised VS Code configurations/npm packages, destroying commit history recoverable only via the GitHub Events API's ~48-hour retention window.
- A detailed community developer guide ('Operation PolinRider') is published covering detection (Unicode/masquerade/git-date scanners), containment, and recovery steps for infected projects.
- Malpedia and Infosec Writeups publish public write-ups after a researcher discovers DPRK malware appended to a personal project's tailwind.config.js file, bringing broad community attention to the config-file-injection technique.
- Synchronized bulk repository modifications occur across the compromised GitHub account 'Xpos587' at 10:00 UTC, pushing malicious Go module versions (git2md, markfetch) and affecting the Artiffusion-Inc/mirofish module and the 7span/sevenspan Packagist namespace.
- Security media report a renewed wave of PolinRider activity hiding JavaScript loaders in open-source repositories, reiterating C2 infrastructure and blockchain dead-drop usage.
- The Hacker News and multiple vendor blogs (Socket, Rescana, SecurityWeek) report a new wave of 108 malicious packages and extensions (162 release artifacts) published across npm, Packagist, Go modules, and the Chrome Web Store, expanding PolinRider beyond its original npm/GitHub focus.
Sources cited for PolinRider: DPRK Supply-Chain Campaign Hides
- I found a malware hiding in my tailwindcss config file
- North Korean Hackers Publish 108 Malicious Packages and Extensions in PolinRider Campaign
- PolinRider: DPRK Threat Actor That Compromised Hundreds of GitHub Repos Is Unmasked
- PolinRider — technical dossier
- Malware Analysis: Tailwind CSS Config Malware
- PolinRider: North Korea-Linked Supply Chain Campaign Expands
- PolinRider Campaign: DPRK-Linked Supply Chain Attack Infects GitHub Repositories
- PolinRider Rides Again: North Korean Attack Expands Across GitHub
- Active Exploitation Alert: North Korean PolinRider Supply Chain Attack Targets npm, Packagist, Go Modules, and Chrome Extensions
- PolinRider
- The Invisible Patch: How PolinRider Rewrites Git History to Hide North Korean Malware
- Contagious Interview: DPRK Threat Actors Lure Tech Industry Job Seekers to Install New Variants of BeaverTail and InvisibleFerret Malware
- PurpleBravo's Targeting of the IT Software Supply Chain
- Operation PolinRider: The Complete Developer's Guide to Detection, Containment, and Recovery
- Surviving PolinRider: How to Recover Your GitHub Repositories After a Mass Force-Push Attack
Threats related to PolinRider: DPRK Supply-Chain Campaign Hides
- ChainVeil and ViteVenom Malware Linked to DPRK PolinRider Supply-Chain Campaign
- PolinRider Campaign: North Korea-Linked Supply Chain Attack Expands Across npm, Packagist, Go Modules, and Chrome Web Store (DEV#POPPER / OmniStealer)
- PolinRider DPRK Supply-Chain Campaign: Confirmed GitHub Footprint Grows 6.5x Since March (JADESNOW/Beavertail/InvisibleFerret Loaders, DEV#POPPER & OmniStealer Payloads)
- PolinRider: North Korea-Linked Supply Chain Campaign Expands Across npm, Packagist, Go Modules, and Chrome Extensions
- North Korea-Linked "Contagious Interview"/Famous Chollima Actors Hide JavaScript Loaders (PolinRider) in Open-Source Packages
- Joyfill npm Packages Compromised with Blockchain C2 Loader
Detection coverage for TL-2026-1143
As of 2026-06-21, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1143 across Splunk SPL, Microsoft KQL and Sigma, covering 53 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.
Community OSINT corroboration for TL-2026-1143
1 of this threat's indicators have also been reported by the open-source security community, which observed at least one of them before this report was published. Community sightings are unverified and are kept separate from Threadlinqs' curated indicators. Indicator values, reporters and campaign linkage are available to authenticated Red-tier users.