Safeguard
Open Source Security

Malicious npm packages targeting developers in 2025

A year-end look at 2025's npm supply chain attacks—chalk/debug phishing, the Shai-Hulud worm, and industrialized malware campaigns—and how to defend against them.

Safeguard Research Team
Research
7 min read

Between January and December 2025, security researchers tracked more than 454,600 newly published malicious packages across open source registries — pushing the cumulative count of known, blocked open source malware past 1.2 million. Npm absorbed the overwhelming majority of that volume: more than 99% of all open source malware activity in 2025 occurred on the JavaScript registry, and by the fourth quarter that figure had climbed to 99.8%. What began the year as a steady drip of credential stealers and typosquats ended it as something closer to an industrial supply chain, with worm-like self-propagation, nation-state-linked campaigns, and automated package-generation pipelines producing a new malicious npm package roughly every seven seconds during at least one campaign. For engineering and security teams that depend on the npm ecosystem — which is to say, nearly every organization shipping JavaScript or TypeScript software — 2025 was the year software supply chain risk stopped being theoretical.

This report breaks down the year's defining incidents, the structural shift from opportunistic to industrialized attacks, and what security teams need to change about how they consume open source dependencies going forward.

The Chalk and Debug Compromise: When Trust Itself Is the Attack Surface

On September 8, 2025, at approximately 9:00 AM EST, an attacker took over the npm account of a well-known maintainer through a convincing phishing email. The message spoofed a two-factor authentication reset notice and was sent from a lookalike domain, npmjs.help. The maintainer entered their username, password, and a live TOTP code into the fake page, handing the attacker full control of their npm publishing rights within minutes.

The attacker used that access to push malicious versions of 18 widely used packages, including chalk, debug, and ansi-styles — libraries that collectively see more than 2.6 billion downloads per week and sit deep in the dependency trees of countless applications that most engineers have never heard of, let alone audited. The injected payload was a browser-side crypto clipper: it silently intercepted wallet activity and web3 transactions, rewriting payment destinations so that funds and token approvals were redirected to attacker-controlled addresses without any visible sign to the end user.

The maintainer caught the compromise and began removing the malicious versions roughly two hours after publication, and npm pulled the remaining tainted releases shortly after. That two-hour window is the detail that matters most: because chalk and debug are transitive dependencies for an enormous share of the npm ecosystem, any CI pipeline, build server, or developer machine that happened to run npm install during that window could have pulled the malicious code without a single line of application code changing. The incident demonstrated that dependency trust is not just a code-review problem — it is an identity and account-security problem that lives entirely outside most organizations' visibility.

Shai-Hulud: The First Self-Propagating npm Worm

One week later, on September 15, 2025, a second and structurally more dangerous attack emerged. Malicious versions of multiple popular packages were published containing a post-install script that used the TruffleHog secret-scanning tool to harvest npm tokens, environment variables, and cloud credentials exposed via instance metadata services. Where the malware found valid credentials on a compromised machine, it automatically used them to publish malicious versions of any other packages that account could reach — spreading laterally across the registry without further attacker involvement. Researchers named it Shai-Hulud, and it is widely regarded as the first successful self-propagating worm in the npm ecosystem. Harvested secrets were exfiltrated to public GitHub repositories the malware created under the same name, and compromised tokens were used to push new GitHub Actions workflows into every repository the stolen credentials could access.

The worm compromised more than 500 packages within days. A second wave, dubbed Shai-Hulud 2.0, surfaced in late November 2025, with compromised package versions uploaded between November 21 and 23. That iteration was markedly more sophisticated, executing during the preinstall phase through a script named setup_bun.js that dropped a heavily obfuscated payload. By May 2026, a further resurgence — "Mini Shai-Hulud" — compromised more than 170 npm packages and, notably, two PyPI packages simultaneously, marking the first supply chain worm to jump across registries in a single campaign. The lineage illustrates a trend security teams should treat as a certainty rather than a possibility: once a self-propagating technique works on npm, it gets reused, refined, and ported to adjacent ecosystems.

Industrialized Malware: Lazarus and the IndonesianFoods Campaign

Not every 2025 npm threat relied on account takeovers or worms. A significant share of the year's malicious package volume came from campaigns engineered for scale. Sonatype attributed more than 800 packages to the Lazarus Group, the North Korean state-linked threat actor, with 97% of that activity concentrated on npm — consistent with a broader pattern of DPRK-affiliated operations targeting developers directly, often through fake job interviews, coding challenges, or recruiter outreach that lead victims to install trojanized packages.

Separately, a campaign researchers dubbed IndonesianFoods effectively doubled the total volume of malware on npm in the space of a few days by auto-generating more than 100,000 malicious packages, publishing a new one roughly every seven seconds. Campaigns of this shape are not trying to trick a specific high-value maintainer; they are optimized to flood the registry with typosquats, dependency-confusion bait, and disposable packages designed to be discovered by automated dependency-resolution tools, build scripts, or AI coding assistants that generate import statements without verifying package provenance. The sheer volume renders manual review impossible and pushes the entire ecosystem toward requiring automated, policy-driven gating at the point of ingestion.

Why This Trend Line Keeps Rising

Three structural factors explain why 2025's numbers were worse than any prior year and why the trajectory is unlikely to reverse on its own. First, npm's publishing model still optimizes for low friction — anyone can publish a package or a new version in seconds, and the registry's scale (millions of packages, billions of weekly downloads) makes manual curation infeasible. Second, maintainer accounts remain a soft target: a single phished maintainer with a popular package can distribute malware to more downstream consumers than almost any other attack vector available today, and the September chalk/debug incident showed that even security-conscious, well-known maintainers can be phished. Third, automation has arrived on the attacker's side of the equation just as much as the defender's — campaigns like IndonesianFoods show that generating tens of thousands of plausible-looking malicious packages is now a scripted, repeatable operation rather than a manual effort.

For defenders, this means the traditional controls — pinning versions, reading changelogs, occasional manual audits — no longer scale to the threat. A malicious version published, weaponized, and detected within a two-hour window, or a worm that self-propagates faster than a human can respond, requires tooling that operates at the same speed and same scale as the attack.

How Safeguard Helps

Safeguard is built for exactly this environment. Reachability analysis lets security teams cut through registry-wide noise by identifying which malicious or vulnerable packages are actually exercised in your application's runtime call paths, rather than flagging every package that merely appears in a dependency tree — turning an alert flood like the IndonesianFoods campaign into a short, actionable list. Griffin AI continuously monitors new and updated packages for behavioral indicators of compromise, such as unexpected post-install scripts, credential-harvesting patterns, or exfiltration attempts, so incidents like Shai-Hulud's worm-like propagation can be caught before a tainted version ever reaches a build. Safeguard's SBOM generation and ingestion capabilities give teams a live, accurate inventory of every open source component in use, so when the next chalk-and-debug-style compromise hits, you know within minutes — not days — whether you're exposed. And where a fix is available, Safeguard can open auto-fix pull requests that bump affected dependencies to clean versions automatically, closing the exposure window before an attacker's two-hour head start becomes your incident.

Sources: Semgrep, Wiz, Wiz — Shai-Hulud, Palo Alto Networks Unit 42, Microsoft Security Blog, Sonatype — Open Source Malware Index, Sonatype — Q3 2025 Press Release, CISA Alert

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.