TL;DR
On March 31, 2026, attackers compromised the primary maintainer’s npm account for Axios, the popular JavaScript HTTP client with 83 million weekly downloads. They published malicious versions 1.14.1 and 0.30.4 containing a cross-platform RAT that steals credentials, SSH keys, and cloud tokens from developer machines. Downgrade to Axios 1.14.0 or 0.30.3, rotate secrets, and scan for indicators of compromise.
What happened
Axios is widely used for API clients, frontend-backend communication, integration tests, and developer tooling.
On March 31, 2026, at 00:21 UTC, a threat actor published axios@1.14.1 through a hijacked maintainer account. The package looked almost identical to the legitimate release. Across 86 files, the meaningful change was in package.json: a new runtime dependency named plain-crypto-js.
That dependency was not used by Axios source code. Its purpose was to execute a malicious postinstall script during npm install.
The malicious Axios versions remained live for roughly two to three hours before npm removed them.
If you build, test, or automate APIs with Node.js, this attack targeted your dependency chain directly.
This guide covers:
- How the attack worked
- How to check whether your machine or CI environment was affected
- How to remediate immediately
- How to reduce similar supply chain risk in API workflows
Attack timeline
The operation happened across an 18-hour window:
-
March 30, 05:57 UTC:
plain-crypto-js@4.2.0was published as a clean decoy package. -
March 30, 23:59 UTC:
plain-crypto-js@4.2.1was published with a maliciouspostinstallhook. -
March 31, 00:21 UTC:
axios@1.14.1was released using the compromisedjasonsaaymannpm account. -
March 31, 01:00 UTC:
axios@0.30.4was released, targeting projects still on the0.xbranch. - March 31, ~03:15 UTC: npm unpublished both malicious Axios versions after community reports.
-
March 31, 04:26 UTC: npm published a security-holder stub for
plain-crypto-jsto prevent republishing.
How the maintainer account compromise showed up
The attacker took over the jasonsaayman npm account, associated with the primary Axios maintainer, and changed the registered email to ifstap@proton.me.
Key forensic signals:
- Legitimate Axios releases used GitHub Actions with npm OIDC Trusted Publisher.
- The malicious releases did not include OIDC binding.
- The compromised releases did not include a
gitHeadfield. - No matching GitHub commits existed for the malicious package versions.
- The attacker likely used stolen long-lived npm access tokens to publish manually.
For package maintainers, this is the main lesson: releases without CI/CD provenance should be treated as suspicious, especially for high-impact packages.
How the dependency injection worked
The attacker did not modify Axios source files.
Instead, they added a dependency to package.json:
{
"dependencies": {
"plain-crypto-js": "^4.2.1"
}
}
The dependency was never imported by Axios. It only needed to be installed.
During installation, npm executed the dependency’s postinstall hook, which launched the payload.
This made the diff look small and easy to miss:
- Axios source code appeared unchanged.
- Tests and imports did not reveal the malicious package.
- The payload executed during dependency installation, not runtime execution.
What the malicious package did
Dropper execution
plain-crypto-js executed an obfuscated setup.js file through a postinstall script.
The file used two obfuscation layers:
- XOR cipher using a key derived from
"OrDeR_7077" - Base64 encoding with character reversal
After decoding, the dropper detected the host OS and executed a platform-specific path.
Platform-specific payload paths
macOS
The macOS branch:
- Wrote AppleScript to:
/tmp/6202033
- Executed it with:
osascript
- Downloaded the payload to:
/Library/Caches/com.apple.act.mond
Windows
The Windows branch:
- Copied PowerShell to:
%PROGRAMDATA%\wt.exe
- Executed a VBScript dropper with:
cscript
Linux
The Linux branch:
- Downloaded a Python RAT to:
/tmp/ld.py
- Executed it with:
nohup python3
Command-and-control endpoints
The payload contacted a command-and-control server using platform-specific POST paths:
- macOS:
packages.npm.org/product0 - Windows:
packages.npm.org/product1 - Linux:
packages.npm.org/product2
Known network indicators:
sfrclak.com
142.11.206.73
http://sfrclak.com:8000/6202033
RAT capabilities
The deployed remote access trojan supported:
- Arbitrary shell command execution
- File system enumeration
- File exfiltration
- Process listing
- Process injection
- In-memory binary injection
- 60-second beaconing to C2 infrastructure
For a developer machine, that means the attacker could access:
-
.envfiles - npm tokens
- GitHub tokens
- SSH keys
- Cloud provider credentials
- Database credentials
- API keys
- Secrets stored in environment variables
Anti-forensics behavior
After execution, the dropper attempted to hide evidence by:
- Deleting
setup.js - Deleting the malicious
package.json - Renaming a pre-staged
package.mdreporting version4.2.0topackage.json
This caused npm list to potentially show plain-crypto-js@4.2.0, even though 4.2.1 had already executed.
Do not rely only on current package metadata to determine whether the payload ran.
Attribution
Google Threat Intelligence Group attributed the Axios attack to UNC1069, a suspected North Korean threat actor.
The macOS malware showed significant overlap with WAVESHAPER, a C++ backdoor tracked by Mandiant in February 2026.
The operation matched known supply chain attack patterns:
- Compromise a maintainer or publishing token
- Target a high-volume developer package
- Execute during installation
- Steal credentials and cloud access
- Clean up local artifacts to slow investigation
Check whether you are affected
Run these checks on:
- Developer machines
- CI runners
- Build agents
- Containers used during the attack window
- Any system that ran
npm installornpm ci
The critical window was approximately:
March 31, 2026 00:21 UTC to 03:15 UTC
Step 1: Check installed Axios versions
From each project directory:
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"
If this returns output, the project resolved a compromised version.
Also check lockfiles:
grep -E '"axios": "1\.14\.1"|"axios": "0\.30\.4"|axios@1\.14\.1|axios@0\.30\.4' package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null
Step 2: Check for the malicious dependency
ls node_modules/plain-crypto-js 2>/dev/null && echo "POTENTIALLY AFFECTED"
The directory’s presence is a strong signal that the malicious dependency was installed.
Because the dropper attempted cleanup, absence of this directory does not fully prove safety.
Step 3: Check platform artifacts
macOS
ls -la /Library/Caches/com.apple.act.mond 2>/dev/null
ls -la /tmp/6202033 2>/dev/null
Linux
ls -la /tmp/ld.py 2>/dev/null
Windows PowerShell
Test-Path "$env:PROGRAMDATA\wt.exe"
If any of these artifacts exist, treat the host as compromised.
Step 4: Check network indicators
Search firewall, proxy, EDR, DNS, and CI runner logs for:
sfrclak.com
142.11.206.73
http://sfrclak.com:8000/6202033
If possible, block the C2 domain and IP at the network level.
Step 5: Review CI/CD logs
Review pipeline runs during the exposure window.
Look for commands such as:
npm install
npm ci
yarn install
pnpm install
Any install that resolved axios@1.14.1 or axios@0.30.4 could have executed the payload.
Pay special attention to CI jobs that had access to:
- Deployment credentials
- npm publishing tokens
- Cloud credentials
- SSH deploy keys
- GitHub Actions secrets
- Container registry credentials
Immediate remediation
If you find any indicator of compromise, assume the affected system and its secrets are compromised.
1. Downgrade Axios
For the 1.x branch:
npm install axios@1.14.0
For the 0.x branch:
npm install axios@0.30.3
Then verify:
npm list axios
2. Add package overrides
Use overrides to prevent transitive resolution to the compromised versions.
npm
{
"overrides": {
"axios": "1.14.0"
}
}
Yarn
{
"resolutions": {
"axios": "1.14.0"
}
}
For projects that must stay on the 0.x branch, use:
{
"overrides": {
"axios": "0.30.3"
}
}
3. Remove the malicious dependency
rm -rf node_modules/plain-crypto-js
Then reinstall from a clean lockfile:
rm -rf node_modules
npm ci
If your lockfile references the malicious versions, update it after pinning Axios.
4. Rotate secrets
If the payload executed, rotate all credentials that may have been accessible from the host.
Prioritize:
- npm tokens
- GitHub tokens
- GitLab tokens
- SSH keys
- AWS credentials
- GCP credentials
- Azure credentials
- API keys in
.envfiles - Database credentials
- Container registry credentials
- CI/CD deployment tokens
- Secrets stored in shell profiles or environment variables
Do not rotate secrets from the compromised host. Use a clean machine.
5. Block known C2 indicators
As a temporary local block on Unix-like systems:
echo "0.0.0.0 sfrclak.com" | sudo tee -a /etc/hosts
Also block at:
- DNS resolver
- Firewall
- Proxy
- EDR
- Cloud egress controls
6. Rebuild compromised machines
If RAT artifacts are found, do not trust the system.
A RAT with shell execution and file access can modify files, install persistence, and tamper with tooling.
Recommended response:
- Preserve evidence if your incident response process requires it.
- Remove the host from the network.
- Rebuild from a known-good image.
- Reinstall dependencies from clean lockfiles.
- Rotate secrets from a clean environment.
Long-term defenses for JavaScript and API teams
Pin exact dependency versions
The attack benefited from semver ranges.
If your package.json used this:
{
"dependencies": {
"axios": "^1.14.0"
}
}
npm could resolve 1.14.1 during the attack window.
Prefer exact versions for critical dependencies:
{
"dependencies": {
"axios": "1.14.0"
}
}
Also commit your lockfile:
git add package-lock.json
In CI, prefer:
npm ci
over:
npm install
npm ci installs from the lockfile and fails if the lockfile and package.json are out of sync.
Disable install scripts where possible
The malicious package executed through postinstall.
In CI/CD, test whether your project can install with scripts disabled:
npm ci --ignore-scripts
You can also set this in .npmrc:
ignore-scripts=true
This may break packages that require native compilation or setup scripts, so validate before enforcing globally.
Audit dependencies in CI
Add dependency checks to your pipeline:
npm audit
You can also run third-party supply chain scanners where appropriate:
npx socket-security/cli audit
Use audit results as a deployment gate for high and critical findings.
Verify package provenance
npm supports package provenance through Sigstore.
Check signatures with:
npm audit signatures
The compromised Axios versions lacked OIDC provenance. For high-impact dependencies, missing provenance on a new release should trigger review before adoption.
Monitor for unexpected dependency changes
Add a CI step that fails when lockfiles change unexpectedly.
Example:
git diff --exit-code package-lock.json
For pull requests, review:
- New runtime dependencies
- New transitive dependencies
- Packages with install scripts
- Packages with low download counts
- Packages published very recently
- Packages without repository metadata
- Packages without provenance
Reduce your HTTP client dependency surface
API testing workflows often add HTTP client dependencies such as Axios, node-fetch, or got.
For production code, those libraries may still be appropriate. But for API testing, debugging, and documentation, you can often reduce npm dependency exposure by using a dedicated API platform.
Apidog provides a built-in HTTP client for API testing, debugging, mocking, and documentation. That means you can avoid installing third-party HTTP clients in your API testing stack.
Practical ways to reduce dependency surface:
- Use Apidog’s visual test builder instead of Axios-based test scripts.
- Use Apidog’s request inspector instead of custom debugging clients.
- Use Apidog mock servers instead of building mock endpoints with Express and Axios.
- Use Apidog CLI for automated API tests in CI/CD.
This does not remove all supply chain risk, but it removes one common npm dependency path from API testing workflows.
Comparison: HTTP client approaches
| Approach | Supply chain risk | Maintenance burden | Testing capability |
|---|---|---|---|
| Axios + custom scripts | High, because it depends on third-party npm packages | High, because versions and transitive dependencies must be managed | Manual setup required |
Node.js native fetch
|
Low, because it is built into the runtime | Low | Limited testing features |
| Apidog built-in client | No npm HTTP client dependency | Platform-managed | API testing, mocking, debugging, and docs |
curl / httpie scripts |
Low, because they are system-level tools | Medium | Limited automation |
What this means for npm security
The npm trust model depends heavily on maintainer account security.
A single compromised maintainer credential or long-lived token can affect millions of downstream installs.
Important ecosystem-level defenses include:
- OIDC-based publishing instead of long-lived npm tokens
- Mandatory provenance for high-impact packages
- Two-person approval for critical releases
- Better detection for suspicious dependency additions
- Safer handling of install scripts
- Runtime permission scoping similar to Deno’s model
For application teams, the takeaway is simpler: treat every dependency as an execution path.
If it can run during install, it can become part of your attack surface.
FAQ
Is Axios safe to use now?
Yes. Axios 1.14.0 and 0.30.3 are clean according to the provided incident details. The compromised versions were 1.14.1 and 0.30.4.
Verify your installed version:
npm list axios
Also check your lockfile.
How do I know if the RAT ran?
Check for these artifacts:
macOS
/Library/Caches/com.apple.act.mond
/tmp/6202033
Linux
/tmp/ld.py
Windows
%PROGRAMDATA%\wt.exe
Also check for:
node_modules/plain-crypto-js
Because the dropper attempted cleanup, missing artifacts do not guarantee the host was safe if it installed a compromised version.
Should I stop using Axios?
Not necessarily.
Axios remains a widely used HTTP client. The better question is where you need it.
For application code, evaluate Axios against alternatives like native fetch in Node.js 18+.
For API testing workflows, consider moving requests into tools like Apidog so your tests do not require an npm HTTP client dependency.
How do I reduce supply chain risk in Node.js projects?
Start with these controls:
- Pin exact dependency versions.
- Commit lockfiles.
- Use
npm ciin CI/CD. - Test
npm ci --ignore-scripts. - Audit dependencies on every build.
- Verify package provenance with
npm audit signatures. - Review new transitive dependencies.
- Minimize unnecessary packages.
- Rotate tokens regularly.
- Prefer OIDC publishing over long-lived npm tokens.
Was this related to the Claude Code source leak?
Both events happened on March 31, 2026, but they were unrelated.
The Axios incident was a deliberate supply chain compromise attributed to a suspected state-sponsored threat actor.
The Claude Code leak resulted from a Bun build tool issue that shipped source maps in production.
Who was behind the Axios attack?
Google Threat Intelligence Group attributed the attack to UNC1069, a suspected North Korean threat actor.
The macOS malware shared significant overlap with WAVESHAPER, a C++ backdoor tracked by Mandiant.
How many developers were affected?
npm has not published official impact numbers in the provided incident details.
The malicious versions were live for roughly two to three hours. Given Axios’ 83 million weekly downloads, the potential exposure was significant.
Can Apidog help prevent this type of issue?
Apidog can reduce one specific attack path: npm HTTP client dependencies in API testing workflows.
By using Apidog’s built-in HTTP client for testing, debugging, mocking, and documentation, you do not need to install Axios, node-fetch, or similar libraries just to run API tests.
That reduces your dependency surface, though it should be combined with broader supply chain controls.
Key takeaways
- The Axios attack used a compromised maintainer account to publish malicious versions.
- The affected versions were
axios@1.14.1andaxios@0.30.4. - The malicious dependency
plain-crypto-jsexecuted through apostinstallhook. - The payload deployed a cross-platform RAT targeting macOS, Windows, and Linux.
- Treat affected machines as compromised and rotate secrets from a clean environment.
- Pin exact versions and commit lockfiles.
- Use
npm ci, and test--ignore-scriptsin CI/CD. - Verify provenance with
npm audit signatures. - Reduce unnecessary npm dependencies in API testing workflows.
Every package in node_modules is a trust decision. Make those decisions intentionally.
Top comments (0)