Packages you legitimately depend on, compromised upstream, arriving in your bundle through the same pipeline everything else uses.
Published 31 March 2026
Updated 24 August 2026
Everything else we track gets onto a page by breaking in. This gets on by being invited: a package you chose, installed on purpose, built into your bundle by the pipeline that builds everything else.
The hosts here are exfiltration endpoints from separate incidents where a widely used npm package was taken over at the source and published with code added. One targeted wallet keys. Another was a compromise of one of the most downloaded HTTP clients in the ecosystem. A third was a template library whose earlier compromise had been cleaned up, then compromised again.
These takeovers are rarely clever attacks on source code. They are attacks on the ability to publish: a phished maintainer, a stolen token, a stale credential in a CI configuration.
That matters for where you go looking. The public repository frequently still shows exactly the code you would expect, because the tampering happened between the source and the registry. Reading the GitHub page for a package tells you nothing about what npm actually served you.
A lockfile is a genuinely good control and it solves the adjacent problem. It stops your dependencies moving without you noticing, which rules out the version of this attack where a bad release arrives through an automatic upgrade.
It does nothing once the version you deliberately install is already compromised. Somebody bumps a dependency, CI is green, review passes, the lockfile records the choice — and then pins you to it with excellent reliability. Reproducibility is not integrity. A lockfile guarantees everyone builds the same thing, not that the thing is safe.
Subresource Integrity has a matching gap. It protects a script fetched from a URL against that file changing underneath the hash, which is exactly right for a CDN-hosted library. It cannot help with a package you installed and bundled, because the hash is computed over what you built, and what you built already contains the malicious code.
Stolen data has to leave. Whatever the entry route, at some point code in the browser opens a connection to somewhere the attacker controls, and that destination has no business being in your policy.
That is why this is visible from the browser even when it is invisible everywhere else. Your build is reproducible, your dependencies are pinned, your repository is clean, and the page still tries to talk to a host nobody authorised.
Watch for a connection to an unfamiliar host from a page whose own files did not change, and treat a new destination appearing shortly after a dependency bump as the two facts belonging together until shown otherwise.
The practical control is the same one that works against everything else here: a connect-src that
names the origins your pages are allowed to reach, derived from what they legitimately need. It does
not care how the code got onto the page, which is what makes it useful against a route that arrived
through your own pipeline with a review and a green build behind it.
These are the entries in our threat intelligence feed for this campaign, shown exactly as we match them. An entry starting *. covers that domain and everything under it, so an attacker cycling through subdomains doesn't get away from it. We only do that when the attacker registered the domain themselves.
The feed changes as we go. We add hosts when they show up and pull them out when the evidence no longer holds, so this is what we're matching today rather than a permanent record.
cfww.shopjiathis.coml1ewsu3yjkqeroy.xyzsfrclak.comsol-rpc.xyzutaq.cfww.shopv3.jiathis.comCorroborated by external research. We classify these on what we saw them doing, not on any claim about who runs them.
We flag these hosts in your own reports automatically, so you hear about it from us instead of from your customers.
← All threat intelligence research · Read this page as Markdown