Attackers compromised the npm account of the lead maintainer of Axios, a widely used JavaScript HTTP client library, and used it to publish malicious versions of the package that deployed a cross-platform remote access trojan on developer machines. The incident represents the highest-impact npm supply chain attack on record given Axios’ approximately 100 million weekly downloads and its presence in frontend frameworks, backend services, and countless enterprise applications.
Luckily the trojanized versions, axios@1.14.1 and axios@0.30.4, were detected by multiple security companies monitoring the npm registry within minutes of publication, triggering a rapid response that saw the malicious packages removed by the npm team between two to three hours later. That said, given the high download activity this project sees, the short time window was enough to impact a significant number of developer environments.
According to cloud security firm Wiz, Axios is used in 80% of cloud and code environments; the company observed execution of the malware in roughly 3% of impacted environments. Researchers with security firm Snyk noted that “even a two-hour malicious window represents an enormous potential blast radius” given the library’s popularity. Almost 175,000 other projects on npm list Axios as a dependency, meaning this had a huge cascade effect through the ecosystem.
The attack follows a series of supply chain attacks that impacted multiple open-source projects across different package repositories over the past several weeks, most of them attributed to a group known as TeamPCP. However, the Google Threat Intelligence Group (GTIG) has attributed the Axios attack to a North Korean threat actor it tracks as UNC1069.
“North Korean hackers have deep experience with supply chain attacks, which they’ve historically used to steal cryptocurrency,” said John Hultquist, chief analyst with GTIG. “The full breadth of this incident is still unclear, but given the popularity of the compromised package, we expect it will have far reaching impacts.”
In their analysis, Snyk researchers also noted the sophistication of techniques involved in the attack.
“The attacker also showed meaningful operational sophistication, pre-staging the malicious dependency, using a ‘clean’ version history, double-obfuscating the dropper, building platform-specific RATs, and implementing anti-forensic self-deletion,” the Snyk researchers said in their report. “This was not opportunistic.”
How the attack unfolded
Attackers began preparing the Axios attack roughly 18 hours before when an account named nrwise published a package called plain-crypto-js@4.2.0. This was a clean decoy designed to establish registry history and legitimacy. The malicious payload arrived later the same day in plain-crypto-js@4.2.1, which contained a postinstall hook that would execute a dropper script when it was pulled in by a different package as a dependency.
Shortly after midnight UTC on March 31 a new version of the Axios package, axios@1.14.1, was published on npm followed by axios@0.30.4 39 minutes later. Both listed plain-crypto-js@4.2.1 as a dependency in their package.json files, but the rest of the components remained unchanged.
A package that appears in the manifest but has zero usage or imports in the codebase is called a phantom dependency and is a high-confidence indicator of compromise, according to researchers at StepSecurity. Another indicator was that these versions appeared only on npm and not in the project’s GitHub repo as tagged releases.
Axios’ legitimate 1.x releases were configured to use npm’s OIDC Trusted Publisher mechanism bound to GitHub Actions, but the 1.14.1 release was published manually via a stolen token with no corresponding commit or tag in the repository.
In comments on GitHub, the project’s principal maintainer Jason Saayman acknowledged that while v1.x had trusted publishing configured, the v0.x branch still relied on a legacy long-lived token. A community member further pointed out that the v1.x publish workflow still passed NODE_AUTH_TOKEN to npm, which takes precedence over OIDC when both are present, meaning the long-lived token was also being used for v1.x rather than the intended trusted publishing mechanism.
Cross-platform malware
The obfuscated and encrypted postinstall script contacted a command-and-control (C2) server on a domain registered the day before by the attackers and downloaded platform-specific second-stage RAT payloads.
On macOS, the binary is written to /Library/Caches/com.apple.act.mond and can self-sign injected payloads via codesign —force —deep —sign, bypassing macOS Gatekeeper protections. The malware fingerprints the system, collects hostname, username, macOS version, boot and install times, CPU architecture, and running processes, and then reaches out to the C2 server every 60 seconds.
On Windows machines the payload is a PowerShell script copied to %PROGRAMDATA%\wt.exe, masquerading as Windows Terminal. The malware establishes persistence through a registry Run key named “MicrosoftUpdate” and a re-download batch file. Meanwhile Linux systems receive a Python script stored as /tmp/ld.py that gets executed via nohup python3.
The RAT supports four commands: peinject for deploying additional binaries, runscript for executing shell or AppleScript code, rundir for directory enumeration, and kill for self-termination.
According to researchers from security firm Socket, after execution the malware attempts to erase its tracks by deleting setup.js, removing the malicious package.json that contained the postinstall hook and replacing it with a clean copy that reports version 4.2.0 instead of 4.2.1. This means users running npm list in an affected project directory will see plain-crypto-js@4.2.0, potentially misleading them into believing the installed version predates the attack.
Detection and maintainer response
Security firms monitoring npm flagged plain-crypto-js@4.2.1 within minutes after it was published, triggering a series of responses, including by the npm registry team that removed the packages. However, the Axios project itself had difficulty containing the issue because the incident happened during the lead maintainer’s nighttime.
A core collaborator of the project responded to the community-reported issue on GitHub also within minutes, but his permissions were lower than those of the maintainer whose token was compromised.
This underscores a potential incident response gap open-source projects might face, because even if project contributors notice a breach immediately, the attacker could have higher privileges than them through a stolen token and could slow down attempts at damage control.
In the recent Trivy compromise, attackers flooded the GitHub issue with spam comments from bots to make it harder for maintainers to respond and communicate with the community.
Prepare for more compromises
The cascade effect of the Axios incident became visible as dependency scanning tools flagged hundreds of downstream projects that had pulled the malicious versions. One user posted warnings to more than 50 repositories after detecting plain-crypto-js in their lockfiles, while another identified dozens more, from personal blogs to enterprise apps.
This demonstrates how quickly the compromise of a popular npm package propagates through the ecosystem, even if the breach is detected within a few hours.
Organizations should audit lockfiles and installed dependencies for the malicious versions immediately. If the malicious versions were installed, assume the development environments are fully compromised. Security teams should isolate affected systems, rotate all credentials present on them such as npm tokens, cloud provider keys, SSH private keys, CI/CD secrets, etc.
“Do not rotate in place; revoke and reissue,” the Snyk researchers advised. “Do not attempt to clean compromised systems. Rebuild from a known-clean snapshot.”
In the long term, organizations should enforce npm ci —ignore-scripts in CI/CD pipelines to prevent postinstall hooks from executing during automated builds and consider package age policies such as npm’s minimumReleaseAge setting. This gives development teams the ability to block the installation of packages that don’t have a minimum age, which would have blocked this attack since “plain-crypto-js” existed for less than 24 hours before being pulled into Axios’ dependency tree.
The use of AI tools like Claude Code or OpenAI Codex in enterprise environments via their respective desktop apps extend the impact past developer environments. These tools are increasingly being used by non-developers in their work workflows, and LLMs tend to rely heavily on the npm and PyPI ecosystems for CLI tools.






