CVE-2025-62718: The Axios Crisis — A Critical SSRF Vuln, a North Korean Supply Chain Attack, and Why Every Node.js Developer Needs to Act Right Now
Axios — 100 million weekly npm downloads, used in practically every Node.js application on the planet — got hit twice in two weeks. On March 31, 2026, North Korean state actors hijacked the lead maintainer's npm account and deployed a cross-platform RAT through a malicious dependency.
Axios sits in practically every JavaScript project you've ever shipped. It's the HTTP client that every tutorial reaches for first, the library that shows up as a transitive dependency when you didn't even ask for it. Over 100 million weekly downloads. The number is almost meaningless at that scale.
In the span of 11 days in April 2026, Axios became the center of two separate security disasters that, taken together, represent the kind of supply chain nightmare that keeps security teams awake. If you use Axios anywhere, in any project, in any pipeline — you need to read this.
The first event: on March 31, 2026, North Korean state actors from the threat group tracked as UNC1069 (also known as Sapphire Sleet and BlueNoroff by Microsoft) compromised the npm account of Axios's lead maintainer and published two backdoored versions containing a cross-platform Remote Access Trojan. The malicious packages were live for three hours. An estimated 600,000 installs may have occurred.
The second event: on April 9, 2026, CVE-2025-62718 was published — a Critical-rated vulnerability (CVSS 9.3) in Axios's handling of NO_PROXY rules that enables Server-Side Request Forgery by routing requests through attacker-controlled proxies, bypassing the internal service protections developers specifically configured to stop SSRF.
These are separate vulnerabilities. Different mechanisms, different severity vectors, different patch versions. But they hit the same library within the same fortnight, and the combined impact for teams running vulnerable versions is catastrophic.
CVE-2025-62718
This is a cybersecurity vulnerability that starts with two characters: a trailing dot and a pair of square brackets. Sounds minor. The consequences aren't.
What NO_PROXY Is Supposed to Do
When you deploy a Node.js application in a corporate or cloud environment, you typically run through an HTTP proxy for outbound traffic. You configure this with environment variables:
HTTP_PROXY=http://your-proxy.company.com:8080
HTTPS_PROXY=https://your-proxy.company.com:8080
NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8
NO_PROXY tells the HTTP client: for these hosts and ranges, skip the proxy and connect directly. This matters for security in two directions. First, you don't want to leak internal service traffic to an external proxy. Second, you don't want to accidentally allow proxy traversal to internal metadata endpoints — like AWS's http://169.254.169.254/latest/meta-data/, which returns IAM credentials to any process that can reach it.
Many SSRF defenses are built on this model. You configure the proxy, you configure NO_PROXY to list loopback addresses and internal ranges, and you trust that requests to those addresses won't go through the proxy.
Axios broke that trust.
The Hostname Normalization Failure
RFC 1034, Section 3.1 defines a hostname with a trailing dot as a fully qualified domain name (FQDN). At the DNS level, localhost. and localhost resolve identically. RFC 3986, Section 3.2.2 governs URI authority, which includes hostname syntax including IPv6 literal notation.
Axios performs a literal string comparison against NO_PROXY entries. It does not normalize hostnames before comparison.
This means:
localhostis in yourNO_PROXYlist → request goes direct. Correct.localhost.(trailing dot) is NOT in yourNO_PROXYlist → request goes through the proxy. Incorrect. It should match.::1is in yourNO_PROXYlist → request goes direct. Correct.[::1](IPv6 literal with brackets) is NOT in yourNO_PROXYlist → request goes through the proxy. Incorrect. It should match.
The official GitHub Security Advisory (GHSA-3p68-rc4w-qgx5), published by Axios maintainer jasonsaayman on April 9, 2026, includes a working Proof of Concept demonstrating the bypass:
import http from "http";
import axios from "axios";
const proxyPort = 5300;
// A simple proxy server that logs everything it receives
http.createServer((req, res) => {
console.log("[PROXY] Got:", req.method, req.url, "Host:", req.headers.host);
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("proxied");
}).listen(proxyPort, () => console.log("Proxy listening on port", proxyPort));
// Set up proxy with NO_PROXY that should protect loopback
process.env.HTTP_PROXY = `http://127.0.0.1:${proxyPort}`;
process.env.NO_PROXY = "localhost,127.0.0.1,::1";
async function test(url) {
try {
await axios.get(url, { timeout: 2000 });
} catch {}
}
setTimeout(async () => {
console.log("\n[*] Testing http://localhost.:8080/");
await test("http://localhost.:8080/"); // ← goes through proxy despite NO_PROXY
console.log("\n[*] Testing http://[::1]:8080/");
await test("http://[::1]:8080/"); // ← goes through proxy despite NO_PROXY
}, 500);
Expected output: Both requests bypass the proxy and connect directly to loopback.
Actual output: The proxy logs both requests. Both loopback variants went through the proxy despite the NO_PROXY configuration listing all loopback addresses.
Source: The PoC is from the official Axios security advisory at github.com/axios/axios/security/advisories/GHSA-3p68-rc4w-qgx5, credited to reporter AmeerAssadi.
The SSRF Chain
Standing alone, routing a request through a proxy when it should go direct sounds like a configuration nuisance. The actual threat surfaces when you combine this with user-controlled input and an attacker-controlled proxy.
The attack chain looks like this:
- Your application takes a URL from user input and passes it to
axios.get(url) - Your
NO_PROXYconfiguration lists loopback and internal addresses to prevent SSRF to internal services - The attacker provides
http://localhost.:8080/admininstead ofhttp://localhost:8080/admin - Axios doesn't normalize the trailing dot, the
NO_PROXYcheck fails to match, and the request routes through the configured proxy - If the proxy is attacker-controlled (or if the attacker can manipulate
HTTP_PROXY), they receive the full response from your internal service
In containerized environments, this gets worse. The Docker container networking model means internal services accessible on loopback from within the container — your local Redis, your local config API, your local admin interface — are all reachable via localhost. Any of these that your application talks to via Axios, with NO_PROXY as the guard, are now potential SSRF targets.
AWS makes this devastating. The instance metadata service endpoint http://169.254.169.254/latest/meta-data/iam/security-credentials/ returns temporary AWS access keys. The path http://169.254.169.254/ is an IPv4 link-local address. While that specific address isn't affected by the trailing-dot bypass in the same way as localhost, any internal service reachable by loopback addresses is. And in Kubernetes environments where sidecars communicate over loopback, the blast radius is substantial.
CISA's ADP metadata for this CVE marks it with SSVC options Exploitation=poc and Automatable=yes. That last flag matters. The exploit mechanism is simple enough that it can be incorporated into automated scanning and exploitation tooling without requiring manual customization per target.
The CVSS 9.3 Score Breakdown
The CVSS v4 score from the official advisory:
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:L/SC:H/SI:L/SA:L
Breaking this down:
- AV:N (Network) — Exploitable remotely, no physical access required
- AC:L (Low Complexity) — A trailing dot is the entirety of the attack technique
- AT:N (No Attack Requirements) — No special deployment conditions needed
- PR:N (No Privileges) — Attacker needs no authentication or existing access
- UI:N (No User Interaction) — Does not require a user to click anything
- VC:H (High Confidentiality, Vulnerable System) — Can expose sensitive data from the vulnerable application
- SC:H (High Confidentiality, Subsequent System) — Can expose data from internal systems reached via SSRF
All five exploitability metrics are at their worst values. An unauthenticated remote attacker with no special setup and no required user action can exploit this if they can influence URLs passed to Axios in an application using proxy configuration.
Affected Versions and the Fix
CVE-2025-62718 affects all Axios versions prior to 1.15.0 that use NO_PROXY rule evaluation. It was confirmed on Axios 1.12.2 at the time of discovery, but the bug predates that version — any release using the current NO_PROXY evaluation logic is affected.
The fix in 1.15.0: Axios now normalizes hostnames before evaluating NO_PROXY, stripping trailing dots per RFC 3986 and removing brackets from IPv6 literals before comparison.
npm install [email protected]
# or if you're on the 0.x legacy branch, you need to upgrade to the 1.x line
# 0.x does not have a backport fix
11 Days Earlier, North Korean Actors Hit First
If you followed the CVE disclosure, you might have missed what happened 11 days before it.
On March 31, 2026, at approximately 00:21 UTC, a threat actor published [email protected] to the npm registry. At 00:22 UTC, they published [email protected]. Both were tagged as the latest stable releases for their respective version branches. Both contained malware.
The malicious packages were pulled from npm at approximately 03:29 UTC. They were live for three hours and eight minutes. SANS Institute's emergency briefing estimated up to 600,000 installs may have occurred during that window.
How They Got In: Account Compromise
This was not a typosquatting attack. This was not a rogue dependency sneaking in. The attacker compromised the npm account of jasonsaayman, the primary maintainer of the official axios package — the same account that published every legitimate Axios release.
According to the StepSecurity analysis and multiple corroborating sources, the attacker changed the registered email address on the jasonsaayman npm account to [email protected], an attacker-controlled ProtonMail address. This gave them full publishing access to the official axios package.
StepSecurity's automated Harden-Runner tool detected the anomalous C2 contact approximately six minutes after the first malicious version was published — before the broader security community had even noticed.
The Attack Pre-Staging
The attack was pre-staged roughly 18 hours before the malicious packages went live. The attacker published [email protected] to npm first — a fake package with an innocuous-looking name. This was deliberate. Publishing the dependency before the main package gave it time to age past "brand new package" alarms in automated security scanners. When [email protected] hit npm with plain-crypto-js as a dependency, the dependency already had a history.
The attack chain, documented by Google Threat Intelligence Group (GTIG) in their official blog post at cloud.google.com/blog/topics/threat-intelligence/north-korea-threat-actor-targets-axios-npm-package
Step 1: The package.json hook
The malicious axios versions added [email protected] to their dependencies and used npm's postinstall lifecycle hook:
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"postinstall": "node setup.js"
}
}
When npm installs a package, it automatically runs postinstall scripts. No user interaction. No code changes to the Axios library itself. Your application code runs correctly while malware executes silently in the background during installation.
Step 2: SILKBELL — The Double-Obfuscated Dropper
setup.js (SHA256: e10b1fa84f1d6481625f741b69892780140d4e0e7769e7491e5f4d894c2e0e09) is GTIG's named component SILKBELL. It checks the target system's operating system and reaches out to the C2 server at sfrclak[.]com:8000.
The C2 URL path used was /6202033. Huntress's analysis noted this is 3-30-2026 backwards — the date of the attack. The attacker embedded their timestamp in their campaign identifier.
Step 3: WAVESHAPER.V2 — The Platform-Specific RAT
The C2 server delivers a platform-specific second-stage Remote Access Trojan based on the OS detected by SILKBELL:
- Windows:
wt.exewritten to%PROGRAMDATA% - macOS: Persisted to
/Library/Caches/com.apple.act.mond - Linux: Python-based RAT at
/tmp/ld.py
All three variants implement the same capability set: credential harvesting, file access, command execution, and data exfiltration. The WAVESHAPER.V2 backdoor had been previously attributed to UNC1069 in earlier campaigns.
Huntress's analysis noted an operational security tell in the malware: all variants use the User-Agent string mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0) — Internet Explorer 8 on Windows XP. In 2026, this string is so anomalous that Huntress described it as a reliable detection indicator. Any log analysis tool seeing this User-Agent in 2026 should immediately flag it.
The POST bodies to the C2 were designed to mimic npm registry traffic, using the prefix packages.npm.org to blend into SIEM analysis. Huntress noted that npm.org has belonged to the National Association of Pastoral Musicians since 1997 — not npm. Defenders who know their allowed traffic domains catch this.
Step 4: The Anti-Forensic Problem
Here is the detail that should concern every incident responder: after installation, the malicious plain-crypto-js package directory shows a completely clean package.json. No postinstall script. No setup.js. No malicious indicators.
From the UNU Campus Computing Centre analysis:
"Any post-infection inspection of node_modules/plain-crypto-js/package.json will show a completely clean manifest — no postinstall script, no setup.js, no indication anything malicious was ever installed. Running npm audit or manually reviewing the installed package directory will not reveal the compromise."
The malicious content executes and then cleans up its own evidence. Standard forensic inspection of node_modules won't show you what happened. If you were in the exposure window, you cannot forensically clear yourself by looking at the package directory. Assume compromise.
Attribution: UNC1069, Sapphire Sleet, BlueNoroff
Both Google GTIG and Microsoft Threat Intelligence independently attributed this attack to the same North Korean state actor — Google tracks them as UNC1069, Microsoft as Sapphire Sleet. The group also goes by BlueNoroff, CageyChameleon, and CryptoCore in other vendor taxonomies.
UNC1069 has been active since at least 2018. The group is financially motivated, targeting cryptocurrency exchanges, financial institutions, and developer infrastructure as stepping stones to larger financial theft. Their documented tactics include social engineering, supply chain compromise, and malware deployment at scale.
GTIG's Yara rule for WAVESHAPER.V2 detection on Windows, from their official blog post:
rule G_Backdoor_WAVESHAPER.V2_PS_1 {
meta:
description = "Detects the WAVESHAPER.V2 PowerShell backdoor which communicates with C2 via base64 encoded JSON beacons and supports PE injection and script execution"
author = "GTIG"
md5 = "04e3073b3cd5c5bfcde6f575ecf6e8c1"
date_created = "2026/03/31"
date_modified = "2026/03/31"
rev = 1
platforms = "Windows"
family = "WAVESHAPER.V2"
strings:
$ss1 = "packages.npm.org/product1" ascii wide nocase
$ss2 = "Extension.SubRoutine" ascii wide nocase
$ss3 = "rsp_peinject" ascii wide nocase
$ss4 = "rsp_ru" ascii wide nocase
// ... (see GTIG blog for complete rule)
}
Source: cloud.google.com/blog/topics/threat-intelligence/north-korea-threat-actor-targets-axios-npm-package by Google Cloud GTIG.
The OpenClaw Connection
The Snyk analysis of the supply chain attack documented two secondary npm packages that were also shipping the malicious plain-crypto-js dependency:
@qqbrowser/[email protected]— included a tampered[email protected]with the injected dependency@shadanai/openclaw— similar
If you've been following our OpenClaw coverage, this is the supply chain attack vector we warned about. The ClawHub skill marketplace and the broader OpenClaw ecosystem created exactly the kind of proliferating dependency tree that attackers target. An agent framework with 13,000+ community skills, many of which pull npm dependencies transitively, is a high-value target for exactly this kind of poisoning. The UNC1069 operation deliberately targeted OpenClaw-adjacent packages, either to reach developers building on the framework or to reach end-users running OpenClaw agents that themselves ran npm install.
Full IOC List
These are the confirmed Indicators of Compromise from the supply chain attack. Block at the firewall, flag in SIEM, search in logs:
| IOC Type | Value |
|---|---|
| Malicious npm versions | [email protected], [email protected] |
| Malicious dependency | [email protected] |
| C2 Domain | sfrclak[.]com |
| C2 IP | 142.11.206.73 |
| C2 Port | 8000 |
| C2 Path | /6202033 |
| Windows artifact | %PROGRAMDATA%\wt.exe |
| macOS artifact | /Library/Caches/com.apple.act.mond |
| Linux artifact | /tmp/ld.py |
| Dropper hash (SHA256) | e10b1fa84f1d6481625f741b69892780140d4e0e7769e7491e5f4d894c2e0e09 |
| Attacker email | [email protected] |
| Anomalous User-Agent | mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0) |
Sources: GTIG, Huntress, Microsoft Threat Intelligence, Tenable, StepSecurity.
Are You Affected? Run These Right Now
For CVE-2025-62718 (SSRF/NO_PROXY)
# Check which version of axios you're running
npm list axios
# Check for axios in your lock file
grep '"axios"' package-lock.json
# If you're on anything below 1.15.0, you're vulnerable
# The fix:
npm install axios@latest
You're vulnerable if:
- You use Axios < 1.15.0
- Your application uses
HTTP_PROXY/HTTPS_PROXYenvironment variables - You rely on
NO_PROXYto protect internal services from SSRF - User input can influence URLs passed to Axios
For the Supply Chain Attack
# Check for malicious versions in your lock file
grep -E '"axios"' package-lock.json | grep -E '1\.14\.1|0\.30\.4'
# Check for the malicious dependency
npm ls plain-crypto-js
# Search node_modules directly (important — don't skip this)
find node_modules -name "plain-crypto-js" -type d
# For Yarn
grep -E 'axios@' yarn.lock | grep -E '1\.14\.1|0\.30\.4'
# For Bun (1.x lockfile)
grep -E 'axios' bun.lock | grep -E '1\.14\.1|0\.30\.4'
bun bun.lockb | grep 'plain-crypto-js'
Check your CI/CD logs for the window March 31, 2026, 00:21 UTC to 03:29 UTC. Any npm install or npm ci run that resolved axios@^1.14.0 or axios@^0.30.0 during this window may have installed the malicious version. Ephemeral CI runners (GitHub Actions) are safer — the runner is destroyed after each job. Self-hosted persistent runners should be treated as fully compromised if they ran during this window.
Check for file artifacts on any system that ran npm during the exposure window:
- Windows:
%PROGRAMDATA%\wt.exe - macOS:
/Library/Caches/com.apple.act.mond - Linux:
/tmp/ld.py
Finding any of these means the RAT was deployed. Treat the machine as compromised regardless of whether the file still exists — the attack cleans up after itself, but cleanup doesn't undo credential theft.
If You're Compromised
Per Microsoft Threat Intelligence and Tenable's incident guidance:
- Rotate every credential that was accessible from the compromised machine. This means AWS keys, GitHub tokens, database passwords, API keys, OAuth secrets — anything in environment variables,
.envfiles, or secrets managers that the process could read. Do this immediately. - Review cloud access logs for your entire environment for unauthorized actions in the hours and days following March 31. The attackers harvest credentials and then often go quiet, using them later.
- Re-image or restore from a verified clean backup taken before March 30, 2026.
- Block C2 infrastructure at the firewall if not already done:
sfrclak[.]comand142.11.206.73:8000. - Audit your downstream supply chain. GTIG warned that "hundreds of thousands of stolen secrets could potentially be circulating" from this and related campaigns. Stolen credentials from one developer machine can propagate into other packages that developer has access to. This incident has legs beyond the initial three-hour window.
SANS's Ed Skoudis was direct about the long game: the credential access from this attack is the real story. Axios was the opening move. The attackers use those credentials to reach other packages, other repositories, other systems. The incident response today is about Axios. The incident response months from now is about everything those stolen credentials enable.
Axios Is Not an Isolated Target
This isn't the only supply chain attack running right now. Security researchers have identified what appears to be a related campaign called TeamPCP, which between March 19 and 27, 2026 — days before the Axios attack — compromised four other widely used open-source projects in rapid succession:
- Trivy (the vulnerability scanner)
- KICS (infrastructure-as-code security scanner)
- LiteLLM (the AI proxy library on Python/PyPI)
- Telnyx (communications library on PyPI)
GTIG has stated the Axios attack is separate from TeamPCP — different threat actors running parallel operations against open-source infrastructure simultaneously. That's the piece that should reset your threat model. This isn't one group running one campaign. Multiple sophisticated threat actors are running independent, concurrent operations against the open-source dependency ecosystem at the same time, targeting different package managers, different languages, different attack surfaces.
We covered this attack category in depth in the supply chain security article. The LiteLLM hit is particularly notable for anyone building AI applications — LiteLLM is the proxy library that sits between your application and every major LLM provider (Claude, GPT, Gemini, Bedrock). If you run LiteLLM, go audit it now independently of the Axios issue.
Long-Term Hardening
The Axios incident reveals specific patterns that your dependency security posture should address permanently.
Pin exact versions. Stop using caret and tilde.
// Bad — this pulls 1.14.x automatically, which pulled malicious 1.14.1
"dependencies": {
"axios": "^1.14.0"
}
// Good — pinned to an exact, known-safe version
"dependencies": {
"axios": "1.14.0"
}
The malicious versions were tagged latest and affected any project using semantic version ranges that allowed minor or patch auto-updates. The entire blast radius of the supply chain attack came from packages that were configured to auto-update.
Always use npm ci in CI/CD, never npm install.
npm install resolves dependencies and can update the lockfile. npm ci installs exactly what's in package-lock.json and fails if the lockfile doesn't match. Commit your lockfile. Require npm ci everywhere in automation.
Require provenance attestations for critical dependencies.
The Axios attack had one glaring detection indicator that many teams missed: legitimate Axios releases include OIDC provenance metadata and SLSA build attestations linking the npm package back to a specific GitHub Actions run. The malicious versions had none — they were published directly, leaving no verifiable build trail.
# Require provenance on install (npm 9+)
npm install --require-provenance axios
Configure your internal npm proxy (Artifactory, Nexus, Verdaccio) to reject packages lacking cryptographic build provenance. The malicious Axios versions would have been flagged immediately — they had no OIDC provenance record.
Implement a version cooldown policy.
SOCRadar's remediation guide recommends implementing package release age policies that reject packages published within the last 72 hours:
// .npmrc — policy example (Artifactory supports this natively)
// Reject packages published within the last 3 days
// This gives the security community time to analyze new releases
Disable postinstall scripts in production builds.
The entire Axios attack vector relied on npm's postinstall lifecycle hook. If your production builds don't need lifecycle scripts (most don't), disable them:
npm ci --ignore-scripts
This would have completely prevented the WAVESHAPER.V2 deployment even if the malicious package was installed. setup.js never runs without the postinstall hook.
For CVE-2025-62718 specifically — don't rely on NO_PROXY alone for SSRF protection.
The correct lesson from this vulnerability is not just "upgrade Axios." It's that any security control implemented as a string comparison against user input is fragile. Defense-in-depth for SSRF should include:
- Network-level egress controls (not just application-level
NO_PROXYsettings) - Allow-listing of external domains rather than blocking internal addresses
- Validation that URLs are not loopback, link-local, or RFC 1918 private ranges before passing them to any HTTP client
- Metadata endpoint blocking at the network layer for cloud-hosted applications
The SSRF article covers the full class of vulnerabilities that CVE-2025-62718 enables. The Capital One breach in 2019 ran on an SSRF chain that reached the AWS metadata endpoint. The same mechanics apply here, enabled by a two-character hostname variant.
Version Summary: What to Be On
| Scenario | Action |
|---|---|
| Axios 1.14.1 | MALWARE. Downgrade immediately to 1.14.0 or upgrade to 1.15.0. Treat system as compromised. |
| Axios 0.30.4 | MALWARE. Downgrade immediately to 0.30.3. Treat system as compromised. |
| Axios < 1.15.0 (not 1.14.1 or 0.30.4) | VULNERABLE to CVE-2025-62718. Upgrade to 1.15.0. |
| Axios 1.15.0 | Safe from both CVE-2025-62718 and supply chain attack. |
| plain-crypto-js anywhere in node_modules | COMPROMISED. Full incident response. |
Check your transitive dependencies too. Axios is a dependency of hundreds of packages. npm ls axios shows you every copy of Axios in your dependency tree, not just your direct dependency.
# Find ALL axios versions in your entire dependency tree
npm ls axios
# Find which packages depend on a vulnerable axios
npm ls axios | grep -E '1\.14\.1|0\.30\.4'
The Conclusion
If you haven't already: run the detection commands above right now. If you find [email protected] or [email protected] anywhere — in your lockfile, in node_modules, in CI logs — treat that system as compromised and start credential rotation immediately. If you find plain-crypto-js anywhere in node_modules, that confirms the dropper ran.
Upgrade everything to [email protected]. That version fixes CVE-2025-62718, and it postdates the supply chain attack entirely.
Then take a longer look at your dependency management posture. The pattern here — compromised maintainer account, postinstall hook, pre-staged malicious dependency, platform-specific RAT, credential harvesting, CI/CD as the blast radius — is not specific to Axios. Every package with a maintainer account, a postinstall script, and millions of downstream users is structurally identical to what got exploited here.
The attackers didn't need a zero-day. They needed one phished npm credential.
The supply chain security article covers the attack patterns behind dependency poisoning, typosquatting, and how adversaries target open-source infrastructure at scale. The SSRF article covers the full technical class of vulnerabilities that the CVE-2025-62718 bypass enables — including the AWS IMDS exploitation chain that makes SSRF in cloud environments so damaging. The OpenClaw deep dive covers why the openclaw-qbot package appearing as a secondary carrier of this attack matters for anyone building on the OpenClaw agent ecosystem.