Skip to main content
1,300 npm Packages Compromised in One WeekIncident
4 min readFor Security Engineers

1,300 npm Packages Compromised in One Week

Imagine running npm install on a trusted package, only to find your AWS credentials are being sent to an attacker's server. This nightmare became a reality for teams using any of 1,300 compromised npm packages between late 2024 and early 2025.

What Happened

The ChainDrop malware campaign compromised over 1,300 npm packages, which collectively had 2 billion monthly downloads. The attack began when threat actors accessed the GitHub account of Keyv's maintainer. They didn't stop at one package; they used GitHub Actions workflows to inject malware into hundreds of dependent packages automatically.

The malware worked in stages. A setup.mjs dropper downloaded the Bun JavaScript runtime, executing the Math_Symbol.js payload. This targeted credentials across your development environment, including AWS keys, GitHub tokens, SSH keys, browser cookies, and Discord tokens.

Timeline

Initial Compromise: Threat actor accessed Keyv maintainer's GitHub account.

Workflow Exploitation: Attacker modified GitHub Actions workflows to inject malicious code during legitimate CI/CD runs.

Propagation: Malware spread to over 1,300 packages through automated dependency updates and publishing workflows.

Credential Theft: Infected packages began exfiltrating credentials from developer machines and CI/CD environments.

Detection: Aikido's security researchers identified the campaign and began analysis.

Which Controls Failed

Three critical control failures enabled this attack:

Account Security: The maintainer's GitHub account lacked protection. Multi-factor authentication was either not enabled or bypassed. There was no evidence of anomalous login detection or session monitoring.

Code Review for Dependencies: Teams were using packages without verifying their provenance. No one checked if the code in the published package matched the repository. There was no monitoring for sudden changes in package behavior or new network calls.

Runtime Monitoring: The malware downloaded a JavaScript runtime (Bun) and executed credential-harvesting code. Your development environments and CI/CD pipelines had no controls to detect or block this behavior.

What Standards Require

NIST 800-53 Rev 5 addresses supply chain risk directly in SR-3 (Supply Chain Controls and Processes). It requires defining security requirements for external system services and monitoring for unauthorized changes. SR-11 (Component Authenticity) calls for anti-counterfeit measures and validation of software authenticity.

ISO/IEC 27001:2022 Annex A.5.19 covers information security in supplier relationships. You're required to assess and monitor supplier security practices. When your "supplier" is an open-source maintainer whose GitHub account gets compromised, you need technical controls to verify what you're installing.

PCI DSS v4.0.1 Requirement 6.3.2 demands maintaining an inventory of bespoke and custom software and third-party components. Requirement 6.4.3 requires script integrity verification for payment pages, but the principle applies to your entire dependency chain: verify what you're running.

SOC 2 Type II CC7.2 (System Monitoring) requires detecting anomalies that could indicate security breaches. If your CI/CD pipeline suddenly starts downloading a new runtime and making network calls to unfamiliar domains, that's an anomaly you should catch.

Lessons and Action Items

Lock Down Maintainer Accounts: If you maintain any package, enable hardware-based MFA on your GitHub account today. Use GitHub's security log to review recent sessions. Set up alerts for logins from new locations or devices.

Implement Dependency Pinning with Hash Verification: Don't use version ranges in production. Pin exact versions and verify package hashes. Tools like npm's package-lock.json help, but you need to review changes when lockfiles update.

Require Provenance Attestations: GitHub's npm provenance feature creates a cryptographic link between published packages and the source code that built them. Start requiring this for new dependencies. For existing ones, prioritize packages with high download counts or access to sensitive data.

Monitor Your Dependency Update PRs: When Dependabot or Renovate opens a PR, don't just merge it. Check the diff. Look for new network calls, new file system access, or downloads of additional runtimes. If a package suddenly needs to download Bun, Python, or any other interpreter, that's a red flag.

Sandbox Your Build Environments: Your CI/CD runners shouldn't have access to production AWS keys or SSH credentials. Use temporary credentials with minimal scope. If a package gets compromised, limit what it can steal.

Deploy Runtime Application Self-Protection: You need visibility into what your dependencies are doing at runtime. Monitor for unexpected network connections, file system access, or subprocess execution. Tools exist for this -- use them.

Audit Your Current Dependencies: Run npm ls or equivalent for your package manager. Cross-reference against known compromised packages. Check for packages that haven't been updated in years but suddenly released a new version. Investigate any package that downloads additional binaries at install time.

Establish a Response Plan: When the next supply chain attack hits -- and it will -- you need to know how quickly you can identify affected systems, rotate credentials, and deploy clean builds. Document this process now, while you're not in crisis mode.

The ChainDrop campaign succeeded by exploiting the trust model of open-source ecosystems. You can't eliminate that risk entirely, but you can make your systems resilient enough that a compromised package becomes a contained incident rather than a credential catastrophe.

Topics:Incident

You Might Also Like