What Happened
For a brief period, attackers published backdoored versions of Axios to npm. Axios is an HTTP client library downloaded millions of times weekly. The malicious packages contained code that enabled remote access and system compromise. Google Threat Intelligence Group attributed the attack to UNC1069, a North Korean threat actor active since at least 2018.
The packages were live for less than three hours. Any CI/CD pipeline that ran during that window and pulled the latest Axios version automatically installed the backdoor.
Timeline
Hour 0: Attackers gained access to the Axios npm publishing account through unknown means.
Hour 0-3: Malicious versions published to npm. The backdoor code was minimal and designed to evade detection. Automated systems and manual reviews failed to catch it.
Hour 3: npm removed the malicious packages after detection.
Post-incident: Organizations scrambled to identify which builds pulled the compromised versions. Many didn't know whether their pipelines had been affected.
Which Controls Failed or Were Missing
Dependency verification: Organizations consuming Axios had no automated verification that package contents matched expected signatures or checksums. Your build pulls whatever npm serves at that moment.
Pipeline isolation: CI/CD systems with network access to production secrets ran untrusted code from npm without sandboxing. The backdoor could exfiltrate credentials, API keys, and deployment tokens during the build process.
Integrity monitoring: No alerting existed for unexpected changes in package behavior or network calls. The malicious code could phone home without triggering security controls.
Supply chain visibility: Teams couldn't quickly answer "did we pull this version?" because they lacked dependency tracking across all builds and environments.
Account security at the source: The Axios maintainer account had insufficient protection. Whether through credential theft, session hijacking, or social engineering, the attackers gained publishing rights.
What the Relevant Standards Require
PCI DSS v4.0.1 Requirement 6.3.2 mandates that you maintain an inventory of bespoke and custom software, and third-party software components. This includes tracking versions. If you can't identify which Axios version each application uses, you can't demonstrate compliance. The requirement exists precisely for this scenario—you need to know what you're running when a vulnerability or compromise emerges.
NIST 800-53 Rev 5 SA-12 (Supply Chain Protection) requires organizations to employ integrity verification mechanisms for software components. This means cryptographic signatures, checksums, or other methods to ensure packages haven't been tampered with. Pulling directly from npm without verification fails this control.
ISO/IEC 27001:2022 Annex A.8.30 (Outsourced Development) addresses security in development involving external parties and supply chains. Your control objectives must include verification of third-party software integrity. Trusting npm's infrastructure without additional validation doesn't meet this requirement.
NIST Cybersecurity Framework v2.0 function PR.DS (Data Security) includes protecting the integrity of data in transit and at rest. Your build artifacts are data. If a compromised dependency can inject code into your application, you've lost integrity control over your software.
SOC 2 Type II CC6.6 (Logical and Physical Access Controls) requires that you restrict access to data and system resources. When your CI/CD pipeline runs arbitrary code from external sources with access to production credentials, you've granted logical access to an untrusted party.
Lessons and Action Items for Your Team
Implement dependency pinning and lock files immediately. Stop using version ranges like ^1.0.0 in package.json. Your lock files (package-lock.json, yarn.lock) should be committed and verified in code review. This won't prevent compromise, but it prevents automatic propagation. You choose when to update, not npm.
Add checksum verification to your pipeline. Tools like npm audit signatures or Sigstore can verify package authenticity. Configure your CI/CD to fail builds if signature verification fails. Yes, this adds friction. That's the point.
Isolate your build environment from production secrets. Your CI/CD runners shouldn't have direct access to production API keys, database credentials, or deployment tokens. Use short-lived credentials issued per-build, and restrict network egress from build containers. If a compromised dependency calls home, it shouldn't be able to reach the internet.
Deploy a Software Bill of Materials (SBOM) tool. You need to answer "which applications use this dependency?" in under an hour, not three days. Tools like Syft, CycloneDX, or your dependency scanner's inventory feature can generate and store SBOMs for every build. When the next supply chain incident hits, you'll know your exposure immediately.
Monitor runtime behavior, not just static signatures. Even if a package passes checksum verification, it might still be malicious if the legitimate maintainer was compromised. Deploy runtime application self-protection (RASP) or eBPF-based monitoring to detect unexpected network calls, file access, or process execution during builds and in production.
Require multi-factor authentication and signing for your own packages. If you publish internal packages to a private registry, enforce MFA for all maintainer accounts and require signed commits. The Axios compromise likely started with weak account security. Don't let your team be next.
Test your incident response for supply chain scenarios. Run a tabletop exercise: "A popular dependency was compromised for two hours last Tuesday. Which of our applications are affected? What data could have been exfiltrated?" If your team can't answer this quickly, your detection and response controls aren't sufficient.
The three-hour window isn't reassuring—it's a wake-up call. It proves that sophisticated attackers can compromise widely-used packages, stay under the radar, and disappear before most organizations even notice. Your controls need to assume npm, PyPI, and every other registry will serve you malicious code eventually. Build accordingly.
npm security best practices



