A malicious npm package does not have to execute during npm install to matter. Sometimes the package is just a storage bucket with better reputation than the attacker could buy.
OX Security reported on August 25 that it found 24 npm packages carrying the same fake Cloudflare CAPTCHA HTML page. The important twist is that installing the packages was not the infection path. The attacker used npm and public mirrors such as unpkg, Yarn mirrors, npmmirror, and Tencent mirrors to render malicious HTML on domains many organizations already trust.
TL;DR
- OX Security found 24 npm packages built around the same fake Cloudflare CAPTCHA page.
- The campaign abused package mirrors as web hosting for phishing or ClickFix-style redirection.
- Installing the package was not the main risk; opening the mirrored
index.htmlURL was.- Reputation-based URL controls can fail when trusted developer infrastructure serves attacker content.
- Defenders should hunt direct HTML requests to package mirror domains and avoid treating mirrors as universally safe.
The Package Is Not The Point
Most npm supply chain incidents focus on install-time execution: preinstall scripts, credential stealers, poisoned dependencies, hijacked maintainers, or compromised CI publishing. This campaign is quieter and, in a way, more irritating.
The package can contain one HTML page and no useful library code. Once mirrors copy it, a URL like this pattern can become a working phishing page:
https://unpkg.example/<package>@<version>/index.htmlThat is not a normal dependency compromise. It is infrastructure laundering. The attacker gets a page served from a legitimate developer CDN, then points victims at that page through email, chat, search abuse, or any other lure.
OX reported that early versions redirected through a Microsoft-login typosquat, login[.]microsofte[.]live. Later versions used api.keyval.org, a legitimate public key-value service, as a remote resolver for the next redirect. That resolver pattern matters because the attacker can change the final destination without changing the npm package.
Today it may send a victim to a harmless-looking site. Tomorrow it can become a credential page, wallet drainer, or ClickFix lure.
Why Mirrors Change The Defender’s Job
Package mirrors exist to make developer workflows faster and more reliable. Security tools often inherit that trust. Blocking all access to unpkg or similar services may break real work, so many environments allow them broadly.
That creates a useful gap for attackers:
| Defender Assumption | Attacker Reality |
|---|---|
| npm risk starts at package installation | Browser-rendered package files can be the delivery surface |
| Mirror domains are developer infrastructure | Developer infrastructure can host attacker-controlled HTML |
| Takedown from npm ends the issue | Mirrors and cached copies may outlive registry removal |
| A clean package scan is enough | The dangerous behavior may be URL redirection, not local execution |
The campaign is small compared with a major maintainer compromise. That does not make it irrelevant. It shows a pattern: registries are not only software supply chains, they are also free publishing systems with reputation, caching, and global reach.
Detection Ideas
Start with web proxy, DNS, and secure web gateway logs. The useful signal is not “user installed a bad npm package.” It is “user’s browser loaded raw HTML from a package mirror.”
Hunt for:
- direct requests to
index.htmlor other.htmlfiles under package mirror paths - fake Cloudflare or CAPTCHA pages served from package CDN domains
- mirror-page JavaScript calling public key-value stores or redirect resolvers
- browser traffic to package mirrors from non-developer endpoints
- email or chat links pointing directly to mirrored package files
A rough proxy pattern:
domain in (unpkg.com, npmmirror.com, yarnpkg.com)and url_path contains "/index.html"and user_agent looks like a browserTune that before alerting loudly. Some front-end documentation and demos legitimately use CDN-hosted HTML or assets. The suspicious combination is raw package HTML, browser rendering, CAPTCHA language, and external redirect behavior.
What To Change
Do not solve this by pretending every developer CDN is malicious. That will fail operationally. Solve it by removing blind trust.
For security teams:
- Add package mirror domains to phishing and URL-reputation pipelines, not only developer allowlists.
- Separate dependency download traffic from human browser traffic where your proxy can see it.
- Alert on direct browser access to raw package HTML from unmanaged or non-developer endpoints.
- Preserve full redirect chains during phishing triage.
- Block CAPTCHA pages that instruct users to copy, paste, or run commands.
For platform teams:
- Prefer pinned internal artifact mirrors for builds.
- Do not let production CI fetch arbitrary package files from public CDN mirrors.
- Treat registry cleanup as incomplete until mirrors and caches are checked.
- Review package allowlists for “domain trusted” shortcuts that bypass path inspection.
The practical lesson is simple: trust belongs to a workflow, not a domain. unpkg.com serving a known library to a build tool is one thing. The same domain serving an unsolicited CAPTCHA page to an accounting user is another.
Related Posts
- The ‘Fix’ Is the Exploit: ClickFix, FileFix, JackFix and Pastejacking Attacks Explained - the social engineering payload this infrastructure can support.
- Minimum Package Age: The Supply Chain Control That Buys Defenders Time - why delaying blind adoption helps, even when takedown is fast.
- GitHub Finally Puts a Human in the Loop: npm Staged Publishing Explained - publication-side controls for npm abuse.
- The Package You Trusted: How the Axios Supply Chain Attack Happened - a classic install-time supply chain compromise for contrast.