PatchDay Alert
MAY 4, 2026
Analysis · 6 min read By Victor Hayes

Three hours was the good outcome: npm's trust model and the Axios compromise

A DPRK threat actor backdoored two Axios versions on npm. Socket flagged the malicious dependency in six minutes. Nothing stopped the downstream publish fifteen minutes later. The system worked exactly as designed.

Three hours was the good outcome: npm's trust model and the Axios compromise

On March 31, 2026, a North Korean state-sponsored threat actor published two backdoored versions of Axios, the HTTP client library with roughly 100 million weekly downloads and 174,121 dependent packages on npm. The malicious versions were live for two hours and 54 minutes before the community detected the compromise and npm pulled them. Socket’s automated scanner flagged the injected dependency within six minutes of publication.

Three hours of exposure across a library that underpins a measurable fraction of the JavaScript ecosystem. And that was the fast version. The system has no architectural protection against a slower, quieter attacker who doesn’t trip the obvious signals.

What one npm account buys you

Sapphire Sleet, the DPRK-linked group Microsoft tracks (Google calls them UNC1069), spent weeks on this operation. They didn’t find a zero-day. They didn’t compromise npm’s infrastructure. They social-engineered one person.

The attacker posed as the founder of a legitimate company, built a fake Slack workspace populated with fake employee profiles and other open-source maintainer identities, and invited the lead Axios maintainer to what looked like a professional collaboration. During a Teams meeting, a fabricated error prompted the maintainer to install what appeared to be a “Teams update.” It was a remote access trojan. That gave the attacker access to authenticated npm sessions, bypassing MFA entirely.

This is the same group linked to the Bangladesh Bank SWIFT heist in 2016 ($81 million), the Ronin Network bridge breach in 2022 (roughly $617 million), and over $10 million in cryptocurrency theft in a six-month period ending early 2026. They invested weeks of social engineering infrastructure for access to one npm account. Because one npm account was sufficient.

Multiple other open-source maintainers, including Mocha’s maintainer, reported similar targeting during the same period.

The six-minute gap that didn’t matter

Here is the timeline that should bother you.

The attacker pre-seeded a clean version of their malicious dependency, [email protected], on March 30 to establish publishing history. The backdoored 4.2.1 went up at 23:59 UTC that same day. Socket’s automated detection flagged it within six minutes.

Fifteen minutes after that flag, the attacker published [email protected] with [email protected] as a dependency. Thirty-nine minutes later, [email protected] followed on the legacy branch. Socket had already flagged the dependency as malicious. It did not matter. No circuit breaker exists between “dependency flagged as malicious” and “package depending on it can still be published.”

The detection worked. The architecture around the detection did not.

Community members filed GitHub issues on the Axios repository. The attacker deleted them using the compromised maintainer account. A collaborator named DigitalBrainJS contacted npm directly. The malicious versions were pulled by 03:15 UTC. Total exposure: about three hours.

What ran on your machine

The backdoored Axios versions added [email protected] to package.json. No source files were modified. The attack is notable for its restraint.

The malicious package used a postinstall hook to deploy a cross-platform RAT. On Windows, a PowerShell-based trojan persisted via the registry Run key (HKCU:\Software\Microsoft\Windows\CurrentVersion\Run\MicrosoftUpdate), though an implementation bug meant it never called its main function on first run, only activating after reboot. On macOS, a universal Mach-O binary landed at /Library/Caches/com.apple.act.mond (Google’s Mandiant team identified this as WAVESHAPER.V2, attributed to UNC1069). On Linux, a Python loader dropped to /tmp/ld.py, which crashed in containers due to os.getlogin() failing without a TTY.

Anti-forensics were minimal but effective: the dropper deleted itself within 15 seconds, leaving clean-looking node_modules.

The implementation bugs are not reassuring. They mean this particular payload was imperfect. They do not mean the delivery mechanism was.

The trust model that made this work

Four properties of npm’s ecosystem combined to make this attack viable at scale.

Postinstall hooks execute arbitrary code with no sandboxing. When you run npm install, any package in the dependency tree can run any command on your machine. That’s the documented behavior. The backdoored Axios versions used this to deploy a RAT. The same mechanism is used by thousands of legitimate packages for build steps. There is no distinction between the two at the platform level.

Semver ranges amplify a single malicious publish. Most package.json entries use the ^ prefix, which accepts any minor or patch version bump automatically. A single malicious publish propagates through semver resolution to every downstream consumer that runs npm install before the package is pulled. With 174,121 dependent packages, the blast radius of a three-hour window is not trivial.

Single-maintainer risk is structural. Axios has a small maintainer team. The attacker needed to compromise one authenticated session. There is no review gate, no second-person approval, no cooling period between publishing a version of a package with 100 million weekly downloads and that version being installable worldwide.

Detection and prevention are decoupled. Socket flagged the malicious dependency in six minutes. That detection produced no automated response. The downstream publish happened anyway. The gap between detection and enforcement is filled entirely by human intervention: filing issues, contacting npm support, waiting.

The escalation pattern

This is not the first npm supply chain compromise. But the trajectory is worth sitting with.

In 2018, the event-stream backdoor involved social transfer of maintainership, targeted cryptocurrency wallets, and went undetected for months. In 2021, ua-parser-js (7 million weekly downloads) was compromised via account takeover and caught in hours. In 2022, the colors.js maintainer sabotaged their own package (roughly 20 million weekly downloads) in a protest that persisted for days.

Axios in 2026: 100 million weekly downloads, state-sponsored social engineering, approximately three hours of exposure. The scale keeps growing. The sophistication keeps growing. The detection keeps getting faster. And the architectural defenses remain the same.

What to do

If you haven’t already checked, do it now.

Search your lockfiles for [email protected] or [email protected]. Run npm ls plain-crypto-js. Check host artifacts: on macOS, look for /Library/Caches/com.apple.act.mond; on Windows, check for %PROGRAMDATA%\wt.exe and the registry key at HKCU:\Software\Microsoft\Windows\CurrentVersion\Run\MicrosoftUpdate; on Linux, check /tmp/ld.py.

If you find any of these: assume breach. Isolate the affected systems, rotate all secrets, rebuild from clean snapshots, and audit your CI/CD pipelines. Google noted that “hundreds of thousands of stolen secrets could potentially be circulating.” eSentire detected 19 affected customers across their base. Unit 42 found impact across 10 industry sectors. EMEA was disproportionately affected due to the timezone of the exposure window.

For prevention going forward: pin exact dependency versions, use npm ci --ignore-scripts in CI pipelines, commit your lockfiles, and look at OIDC-based publishing which ties publishes to CI provenance rather than long-lived tokens.

The uncomfortable part

CISA issued an advisory on April 20, three weeks after the compromise. The community caught it in three hours. The detection tooling caught the signal in six minutes. And still, no automated mechanism prevented the downstream publish.

The system worked as well as it possibly could within its current design. A nation-state with the resources to stage weeks of social engineering, build fake corporate infrastructure, and target individual maintainers got roughly three hours of access to the npm ecosystem’s most-downloaded HTTP client. That’s a good outcome by every historical comparison.

It is also a system where “good outcome” means “we only exposed 174,000 dependent packages to a state-sponsored RAT for the duration of a long lunch.” PatchDay Alert covers supply chain events like this in the daily digest, including the specific version numbers and host artifacts you need to check.

The next attacker will study what tripped the detection and adjust. The question is whether npm’s architecture will adjust first.

Sources

Share

Related field notes

Get the digest

Free. Weekday mornings. Plain English CVE triage.

Check your inbox to confirm.