Crypto

How a Supply Chain Attack Compromised Critical Code Libraries: What Development Teams Need to Know Now

2026-04-01 23:45
485 views
How a Supply Chain Attack Compromised Critical Code Libraries: What Development Teams Need to Know Now

Threat actors compromised an npm access token from axios's lead maintainer and released two malicious versions of the widely-used JavaScript HTTP client library containing embedded malware.

Attackers compromised a long-lived npm access token belonging to an axios lead maintainer and used it to publish two malicious versions of the library that deploy a cross-platform remote access trojan. The poisoned releases—targeting macOS, Windows, and Linux—remained available on the npm registry for approximately three hours before being removed.

Axios is the most widely used HTTP client library in JavaScript, with over 100 million weekly downloads. According to Wiz, it appears in roughly 80% of cloud and code environments, from React frontends to CI/CD pipelines to serverless functions. Huntress detected the first infections just 89 seconds after the malicious package went live and confirmed at least 135 compromised systems among its customers during the exposure window.

This marks the third major npm supply chain attack in seven months. All three exploited maintainer credentials—and this time, the target had implemented every defense the security community recommended.

How the attack unfolded

The attacker gained control of the npm account belonging to @jasonsaayman, an axios lead maintainer, changed the account email to an anonymous ProtonMail address, and published the compromised packages directly through npm's command-line interface. This completely bypassed the project's GitHub Actions CI/CD pipeline.

The axios source code itself was never touched. Instead, both release branches received a single new dependency: [email protected]. The codebase never imports it. The package exists solely to execute a postinstall script that drops a cross-platform RAT onto the developer's machine.

The operation was methodical. Eighteen hours before releasing the malicious axios versions, the attacker published a benign version of plain-crypto-js under a separate npm account to establish publishing history and evade new-package scanner alerts. Then came the weaponized 4.2.1. Both axios release branches were published within 39 minutes. Three platform-specific payloads were pre-compiled. The malware deletes itself after execution and replaces the package.json with a clean version to obstruct forensic analysis.

StepSecurity, which identified the compromise alongside Socket, described it as one of the most operationally sophisticated supply chain attacks ever documented against a top-10 npm package.

The security measures that failed to stop it

Axios had implemented recommended security practices. Legitimate 1.x releases were shipped through GitHub Actions using npm's OIDC Trusted Publisher mechanism, which cryptographically binds each publish to a verified CI/CD workflow. The project maintained SLSA provenance attestations. By contemporary standards, the security posture appeared robust.

None of it prevented the attack. Huntress analyzed the publish workflow and identified the vulnerability. The project still passed NPM_TOKEN as an environment variable alongside the OIDC credentials. When both are present, npm defaults to the token. The long-lived classic token was the actual authentication method for every publish, regardless of OIDC configuration. The attacker didn't need to defeat OIDC—they simply used the parallel authentication path that npm silently prioritized.

"From my experience at AWS, it's very common for old auth mechanisms to linger," said Merritt Baer, CSO at Enkrypt AI and former Deputy CISO at AWS, in an exclusive interview with VentureBeat. "Modern controls get deployed, but if legacy tokens or keys aren't retired, the system quietly favors them. Just like we saw with SolarWinds, where legacy scripts bypassed newer monitoring."

The maintainer posted on GitHub after discovering the breach: "I'm trying to get support to understand how this even happened. I have 2FA / MFA on practically everything I interact with."

Endor Labs documented the forensic differences. Legitimate [email protected] showed OIDC provenance, a trusted publisher record, and a gitHead linking to a specific commit. Malicious [email protected] had none. Any tool checking provenance would have immediately flagged the discrepancy. But provenance verification is opt-in. No registry gate rejected the package.

A pattern across three attacks

Three npm supply chain compromises in seven months. Each began with a stolen maintainer credential.

The Shai-Hulud worm struck in September 2025. A single phished maintainer account provided attackers with a foothold that self-replicated across more than 500 packages, harvesting npm tokens, cloud credentials, and GitHub secrets as it propagated. CISA issued an advisory. GitHub overhauled npm's entire authentication model in response.

In January 2026, Koi Security's PackageGate research revealed six zero-day vulnerabilities across npm, pnpm, vlt, and Bun that circumvented the defenses the ecosystem adopted after Shai-Hulud. Lockfile integrity and script-blocking both failed under specific conditions. Three of the four package managers patched within weeks. npm closed the report.

Now axios. A stolen long-lived token published a RAT through both release branches despite OIDC, SLSA, and every post-Shai-Hulud hardening measure in place.

npm implemented substantial reforms after Shai-Hulud. Creation of new classic tokens was deprecated, though existing ones remained active until a hard revocation deadline. FIDO 2FA became mandatory, granular access tokens were capped at seven days for publishing, and trusted publishing via OIDC provided projects with a cryptographic alternative to stored credentials. Collectively, these changes hardened everything downstream of the maintainer account. What they didn't address was the account itself. The credential remained the single point of failure.

"Credential compromise is the recurring theme across npm breaches," Baer said. "This isn't just a weak password problem. It's structural. Without ephemeral credentials, enforced MFA, or isolated build and signing environments, maintainer access remains the weak link."

Defense mechanisms versus attack reality

What SOC leaders need

npm defense shipped

vs. axios attack

The gap

Block stolen tokens from publishing

FIDO 2FA required. Granular tokens, 7-day expiry. Classic tokens deprecated

Bypassed. Legacy token coexisted alongside OIDC. npm preferred the token

No enforcement removes legacy tokens when OIDC is configured

Verify package provenance

OIDC Trusted Publishing via GitHub Actions. SLSA attestations

Bypassed. Malicious versions had no provenance. Published via CLI

No gate rejects packages missing provenance from projects that previously had it

Catch malware before install

Socket, Snyk, Aikido automated scanning

Partial. Socket flagged in 6 min. First infections hit at 89 seconds

Detection-to-removal gap. Scanners catch it, registry removal takes hours

Block postinstall execution

--ignore-scripts recommended in CI/CD

Not enforced. npm runs postinstall by default. pnpm blocks by default; npm does not

postinstall remains primary malware vector in every major npm attack since 2024

Lock dependency versions

Lockfile enforcement via npm ci

Effective only if lockfile committed before compromise. Caret ranges auto-resolved

Caret ranges are npm default. Most projects auto-resolve to latest minor

Immediate actions for enterprise security teams

SOC leaders whose organizations run Node.js should treat this as an active incident until they confirm clean systems. The three-hour exposure window occurred during peak development hours across Asia-Pacific time zones, and any CI/CD pipeline that executed npm install overnight could have automatically pulled the compromised version.

"The first priority is impact assessment: which builds and downstream consumers ingested the compromised package?" Baer said. "Then containment, patching, and finally, transparent reporting to leadership. What happened, what's exposed, and what controls will prevent a repeat. Lessons from log4j and event-stream show speed and clarity matter as much as the fix itself."

  • Check exposure. Search lockfiles and CI logs for [email protected], [email protected], or plain-crypto-js. Pin to [email protected] or [email protected].

  • Assume compromise if hit. Rebuild affected machines from a known-good state. Rotate every accessible credential: npm tokens, AWS keys, SSH keys, cloud credentials, CI/CD secrets, .env values.

  • Block the C2. Add sfrclak.com and 142.11.206.73 to DNS blocklists and firewall rules.

  • Check for RAT artifacts. /Library/Caches/com.apple.act.mond on macOS. %PROGRAMDATA%\wt.exe on Windows. /tmp/ld.py on Linux. If found, perform a full rebuild.

  • Harden going forward. Enforce npm ci --ignore-scripts in CI/CD. Require lockfile-only installs. Reject packages missing provenance from projects that previously had it. Audit whether legacy tokens coexist with OIDC in your own publishing workflows.

The unresolved vulnerability

Three attacks in seven months. Each different in execution, identical in root cause. npm's security model still treats individual maintainer accounts as the ultimate trust anchor. Those accounts remain vulnerable to credential hijacking, regardless of how many downstream layers are added.

"AI spots risky packages, audits legacy auth, and speeds SOC response," Baer said. "But humans still control maintainer credentials. We mitigate risk. We don't eliminate it."

Mandatory provenance attestation, where manual CLI publishing is disabled entirely, would have prevented this attack before it reached the registry. So would mandatory multi-party signing, where no single maintainer can push a release alone. Neither is enforced today. npm has indicated that disabling tokens by default when trusted publishing is enabled is on the roadmap. Until it ships, every project running OIDC alongside a legacy token has the same vulnerability axios had.

The axios maintainer followed community recommendations. A legacy token nobody realized was still active undermined all of it.