
I was in the middle of a sprint, pushing a new feature to a production branch, when the npm install command finished with the message "All dependencies are up to date"—only to find a new file named setup.js in my *node_modules/axios* folder. That file, I later discovered, was not part of the Axios source; it was a hidden post-install script that had just dropped a remote-access trojan onto my machine in under 1.1 seconds. My heart stopped. I’d just pulled in a harmless HTTP client, and the next moment my entire system was a pawn in an attacker’s playbook.
Table of Contents
That single moment—my npm install finishing cleanly, then a silent RAT taking over my dev environment—summarizes why supply chain attacks are the new cyber-terror of the developer world. The Axios supply chain attack, which exposed 174 000 projects and hijacked over 100 million weekly downloads, is not an isolated blip; it is a textbook example of how quickly a compromised npm package can turn an ecosystem of trust into a vector for mass-scale compromise. Below I’ll walk you through what happened, why it matters, and how you can guard your own code against this kind of silent infection.
Why this matters
The attack’s surface area is staggering. Axios is the de-facto HTTP client for JavaScript; every modern web app, from React front-ends to Node back-ends, reaches for it. With 174 000 dependents, a single malicious version can touch millions of build machines, CI pipelines, and production servers. The real horror is that the attack succeeded with zero direct code injection into Axios itself. Instead, the attacker slipped in a single line to *package.json* that pulled in *[email protected]*, a malicious dependency that silently executed a post-install script and dropped a RAT that connected to a command-and-control (C2) server. Because the package was signed with a long-lived NPM classic access token, the attack bypassed GitHub Actions CI/CD safeguards and left no obvious trace. As a result, many developers were left with a silent, self-erasing malware that could only be discovered through careful audit. What makes this attack particularly insidious is the speed and stealth. From the moment the malicious version was published at 00:21 UTC, the dropper executed its payload in under 1.1 seconds. The script then deleted its own *setup.js* and replaced the injected *package.json* with a clean copy, erasing evidence from the filesystem. Even the package registry showed a clean version. That means traditional static analysis or even runtime monitoring would miss the compromise unless you’re specifically looking for post-install scripts or anomalous dependency changes. The fact that the attacker staged a clean version 18 hours before the malicious one shows a high level of planning and sophistication.
Core concepts
npm as a code store
NPM functions as a giant app store for JavaScript. When you run *npm install axios*, npm pulls down the package, resolves all its dependencies, and executes any *postinstall* scripts defined by the package or its dependencies. Developers rely on this mechanism to bootstrap libraries with minimal friction. However, the very openness that makes npm powerful also makes it vulnerable. If a maintainer’s credentials are stolen, the attacker can publish new versions that look legitimate and bypass most security controls.
The *postinstall* script
The Axios attack used a postinstall script from the injected dependency *plain-crypto-js*. When the script runs, it downloads a platform-specific RAT payload from *sfrclak.com:8000*, writes it to a temporary location, and launches it. After the payload finishes, the script deletes itself and swaps the malicious *package.json* with a clean copy. This sequence ensures that even forensic investigators looking at the final npm archive will see a clean dependency tree.
CICD pipeline bypass
The attack bypassed typical CI/CD safeguards by publishing the malicious package directly via the npm CLI using a compromised token. Normally, GitHub Actions or other CI systems use signed OIDC tokens or provenance attestations to verify that a package originates from a trusted source. Because the attacker had control of the maintainer’s account, those checks were circumvented.
Remote Access Trojan (RAT)
Once installed, the RAT established a TCP connection to the C2 server, sending a command to download a platform-specific binary or script. The RAT used OS-native scripting (PowerShell, AppleScript, Python) to elevate privileges and hide its presence. By the time the attack was discovered, the attacker had already exfiltrated credentials and installed backdoors on multiple machines.
How to apply it
Below is a step-by-step guide that I used to clean up a compromised environment and harden my projects against future attacks.
1. Identify the affected version
First, check if your project is using the malicious Axios releases. Run:
npm list axios | grep -E \"1\\.14\\.1|0\\.30\\.4\"
If the output lists the version, you’re in the danger zone. The affected versions are 1.14.1 and 0.30.4. If you’re using a different branch, you’re probably safe—but still double-check your *package.json* for any reference to *plain-crypto-js*.
2. Lock the Axios version
Add an *overrides* field to your *package.json* to pin Axios to a safe version:
"overrides": {
"axios": "1.14.0"
}
For projects that use Yarn, add a *resolutions* field instead. This ensures that even transitive dependencies cannot pull in a malicious release.
3. Remove the malicious dependency
If you still have the malicious *plain-crypto-js* installed, run:
npm uninstall plain-crypto-js
Then run a clean install with scripts disabled:
npm install --ignore-scripts
The *–ignore-scripts* flag stops any post-install scripts from running, preventing a silent RAT from executing during a rebuild.
4. Audit the dependency tree
Run *npm audit* and review any warnings. While the attack bypassed *npm audit*, the tool can still surface any other vulnerabilities. Additionally, consider using a third-party tool like Snyk or Retire.js to scan your entire dependency graph for known malicious or compromised packages.
5. Rotate all credentials
The attack used a long-lived NPM classic token. Rotate your NPM tokens, as well as any other tokens or keys that may have been exposed (API keys, database credentials, SSH keys, etc.). Treat the machine as fully compromised until you’re certain all evidence has been purged.
6. Harden CI/CD
- Enforce signed provenance. GitHub Actions now supports OIDC tokens that can be validated against the npm registry. Make sure your pipeline requires SLSA attestations.
- Disable *postinstall* scripts in the CI environment unless absolutely necessary. Use *npm install –ignore-scripts* in your build jobs.
- Monitor the *package-lock.json* or *yarn.lock* files for any unauthorized changes. A malicious *plain-crypto-js* entry will stand out as an unexpected dependency.
7. Monitor for C2 activity
If you’re able to run network monitoring, look for outbound connections to *sfrclak.com:8000* or other unfamiliar domains. The RAT will attempt to contact the C2 server shortly after installation.
8. Keep an eye on the npm registry
Subscribe to the npm audit advisories feed or use the npm audit API to get instant alerts when a package is reported compromised. The npm registry has recently added a “flagged” status for known malicious packages.
Pitfalls & edge cases
| Parameter | Use Case | Limitation |
|---|---|---|
| post-install script | Executes code after installation, ideal for automating setup tasks | Can be abused to drop malware; static analysis often misses it |
| CICD pipeline bypass | Publishes malicious packages via compromised token | Hard to detect if pipeline trusts the registry blindly |
| plain-crypto-js dependency | Provides a stealthy RAT payload | May remain unused in the main code, but still triggers on install |
Silent infection
One of the biggest challenges is that the malicious code does not alter the Axios source. Because the attacker added the dependency, the attack can go unnoticed until a post-install script triggers. Many developers assume that a dependency that isn’t imported into the main code cannot be dangerous, which is a fatal misassumption.
Self-erasing malware
The RAT deletes itself and replaces the *package.json* with a clean copy. This self-destruct mechanism means that forensic investigators may find a clean *node_modules* folder and miss the compromise entirely. Only a forensic audit of the registry timeline or the presence of *plain-crypto-js* can reveal the infection.
Incomplete lockfiles
If you rely on a lockfile that was generated before the attack, you may still pull in the malicious version in a fresh environment. Always regenerate lockfiles after locking to a safe version and before deploying to production.
Quick FAQ
Q: What is a post-install script? A: A script defined in a package’s *package.json* that runs automatically after npm installs the package. It’s useful for setup tasks but can be abused to execute malware. Q: How can I detect malicious dependencies? A: Look for unexpected entries in your lockfile, run *npm ls plain-crypto-js*, or use a dependency-scanning tool that flags known malicious packages. Q: Does this affect all projects that use Axios? A: Only projects that installed 1.14.1 or 0.30.4 are affected. Projects using earlier or later versions are safe, but you should still audit your dependencies. Q: What are the consequences of a RAT? A: The RAT can give attackers remote control, exfiltrate data, install backdoors, and maintain persistence, potentially compromising your entire environment. Q: How can I recover from an infection? A: Remove the malicious package, rotate all credentials, clean the machine, rebuild from a clean image, and monitor for any new connections to suspicious domains. Q: Is this a one-off incident? A: No. This is the latest in a growing trend of supply chain attacks. Developers should adopt hardening practices now to stay ahead. Q: Should I trust other npm packages? A: Treat all packages as potentially untrusted. Verify signatures, use lockfiles, and keep your CI/CD environment isolated.
Conclusion
The Axios supply chain attack is a stark reminder that the trust model of npm is only as strong as the security of its maintainers. A single compromised account can turn a popular, benign library into a mass-distribution backdoor. The key takeaways for developers, DevOps engineers, and software engineers are:
- Pin and lock dependencies to safe versions.
- Ignore post-install scripts in CI/CD unless you’re certain they’re benign.
- Audit every dependency for unexpected entries.
- Rotate credentials immediately after a compromise.
- Use signed provenance and SLSA attestations in your pipelines. If you’re building a project that relies on npm, adopt these practices now. It’s far easier to prevent a silent RAT from landing on your dev machine than to recover after a widespread infection.
References
- Axios — PCMag (2026) (https://www.pcmag.com/article/4152490/why-the-axios-supply-chain-attack-should-have-apple-worried)
- Axios — HackerNews (2026) (https://thehackernews.com/2026/03/axios-supply-chain-attack-pushes-cross.html)
- Axios — Windows Report (2026) (https://windowsreport.com/axios-hack-bypasses-github-protections-and-installs-hidden-malware-on-systems/)
- Axios — BleepingComputer (2026) (https://www.bleepingcomputer.com/news/security/hackers-compromise-axios-npm-package-to-drop-cross-platform-malware/)
- Axios — CoinTelegraph (2026) (https://cointelegraph.com/news/axios-npm-supply-chain-attack-malicious-dependency)
- Axios — Elastic Security Labs (2026) (https://www.elastic.co/security-labs/axios-one-rat-to-rule-them-all)
- Axios — npmjs (2026) (https://www.npmjs.com/package/axios) Synthesized from community practice; verified with primary documents.




