On March 31, someone gained access to the npm account of Jason Saayman, the sole maintainer of Axios, and published two malicious versions of one of the internet's most relied-upon HTTP client libraries. The packages were live for roughly three hours before npm removed them. What makes this case different from the DPRK attribution headlines and the download count statistics is the precision of the construction. The attacker changed one file in the Axios package and left 85 others untouched. The source code was clean. The infection hid inside the dependency chain and rewrote itself after installation to erase its own fingerprints.
Socket and StepSecurity published the technical breakdowns within hours of the packages going live. Both reports are thorough. The short version: the attacker first published a malicious dependency called plain-crypto-js@4.2.1, on March 30 at 23:59:12 UTC. Then, using a compromised npm token for Saayman's account, they published axios@1.14.1 and axios@0.30.4 — two versions targeting different release branches. Both malicious Axios packages listed plain-crypto-js@4.2.1 as a dependency.
The malware itself is a remote access trojan, or RAT. Once installed, it beacons to a command-and-control server at sfrclak.com:8000 (IP 142.11.206.73) every 60 seconds, according to Socket. The beacon uses a spoofed Internet Explorer 8 User-Agent string, Elastic Security Labs found, presumably to blend in with legacy Windows traffic. The RAT can run arbitrary commands, inject binaries into memory, and enumerate the filesystem. Three separate implementations exist — PowerShell for Windows, compiled C++ for macOS, Python for Linux — with identical C2 protocols, Elastic's analysis shows. The consistency suggests a single developer or a tightly coordinated team working from a shared design document.
On Windows, the RAT copies PowerShell to %PROGRAMDATA%\wt.exe — disguising itself as Windows Terminal to evade endpoint detection. On macOS, it drops a binary to /Library/Caches/com.apple.act.mond, Socket reported, deliberately mimicking Apple's com.apple.* naming convention to appear as a legitimate system daemon. The dropper uses a two-layer encoding: reversed base64, then XOR with the key OrDeR_7077. StepSecurity's analysis found the malicious Axios versions were byte-for-byte identical to clean versions across all 85 source files — only package.json changed.
The attacker changed the email on Saayman's npm account to ifstap@proton.me to lock him out. A collaborator on the Axios project later said they could not revoke the attacker's access because the attacker's permissions exceeded their own, Socket noted. That detail is worth sitting with: the legitimate maintainer could not regain control of his own package.
Simon Willison, who tracks supply chain attacks closely, identified one heuristic that caught the malicious releases immediately: neither axios@1.14.1 nor axios@0.30.4 had an accompanying GitHub release. Every legitimate Axios release is tagged in the GitHub repository with a signed commit and a release note. These had nothing. The attacker skipped the GitHub step entirely — presumably because creating a fake release would require either compromising Saayman's GitHub account or fabricating commit history, both of which leave more traces than simply publishing to npm. The same no-GitHub-release pattern appeared in the LiteLLM supply chain attack one week earlier, Willison noted.
Socket flagged the malicious package at 00:05:41 UTC on March 31, six minutes after axios@1.14.1 went live. npm removed both versions around 03:15 UTC. The window was roughly three hours. Socradar's compromise assessment is direct: anyone who ran npm install during that approximately three-hour interval should treat the affected machine as fully compromised.
The most sophisticated part of this attack was not the RAT — it was the anti-forensics. After the postinstall script fires, it renames package.md to package.json inside the installed plain-crypto-js directory and changes the version field to 4.2.0. The result: running npm list shows plain-crypto-js@4.2.0, not @4.2.1. The infected machine shows a clean state to anyone checking manually. StepSecurity documented this behavior.
Elastic Security Labs found the macOS RAT implementation exhibits significant overlap with WAVESHAPER, a C++ backdoor Mandiant attributes to UNC1069, the North Korean threat actor cluster. The Hacker News reported Elastic's finding. The overlap is significant but Elastic is careful — "significant overlap" is not "confirmed." DPRK attribution in cybersecurity is often presented more definitively than the evidence warrants. The technique here is the more durable story.
StepSecurity found that axios@1.14.1 broke Axios's own publish security pattern: all legitimate Axios releases since the introduction of npm's trusted publishing feature use an OIDC binding tied to the project's GitHub Actions workflow. The malicious version had no OIDC binding and no gitHead — it was published via a stolen npm access token, manually, outside the automated pipeline. The attacker went around the security gate rather than through it.
The backstory makes this more pointed. An issue open on the Axios GitHub since 2025 — GitHub issue #7055 — explicitly requested that the project adopt npm trusted publishing. The request referenced the Shai-Hulud worm, which compromised more than 500 npm packages in September 2025 using stolen maintainer tokens. The axios team was asking for the exact protection that would have blocked this attack. The ecosystem had not yet implemented it.
npm trusted publishing, introduced in 2023, lets maintainers bind package releases to cryptographic identities tied to their CI/CD pipeline — typically GitHub Actions. When a release is published with an OIDC token from the trusted pipeline, npm can verify it came from the expected source. When it's published with a stolen user-level token, it cannot. The attacker in this case used the latter method.
@shadanai/openclaw versions 2026.3.31-2 and 2026.3.31-1 also contained the plain-crypto-js trojan in vendored dependencies, Socket reported. The same RAT, embedded in a different package. That suggests this is not an isolated operation but infrastructure being circulated.
npm received approximately 2,000 reports of malicious packages in 2025, GitHub's supply chain security team noted. Most were caught and removed quickly. What distinguishes this case is the premedication: 18 hours of staging, three OS-specific payloads, a RAT designed to self-erase traces and disguise its post-infection state, and an OIDC bypass that exploited the gap between what the registry offered and what the maintainer had been told to request.
The attacker knew what they were doing. The question the field now has to answer is whether the fixes being discussed after each incident — trusted publishing, provenance attestation, token scoping — will arrive before the next campaign finds the next gap.
Axios later adopted npm trusted publishing. It should have happened in 2025.