A Thorough Explanation of npm Supply Chain Attacks and the Major Security Enhancements in npm v12
—A Practical Response Guide for Developers—
Introduction
The npm ecosystem is the foundation of JavaScript development, but supply chain attacks via dependencies are becoming increasingly severe. In September 2025, a series of incidents, including the massive compromise of Chalk/Debug and the self-replicating worm "Shai-Hulud," affected packages with a combined total of 2 billion downloads per week.
Then, on June 9, 2026, GitHub announced npm v12 with "breaking changes." The core of this is disabling install script execution during `npm install` by default. GitHub itself describes this as the "single largest code-execution surface" in the npm ecosystem, and they are moving to close this attack vector by default.
In this article, we will summarize the reality of these attacks, the changes in npm v12, their impact, and specific response procedures, based on official information. This is a must-read for those managing projects with many dependencies.
1. What are npm supply chain attacks?
Attackers target popular packages to execute malicious code during installation or usage.
Main attack methods
Maintainer account takeover: Stealing credentials via phishing and publishing malicious versions
Abuse of postinstall / preinstall scripts: Injecting malware (RATs, credential theft, self-propagating worms, etc.) into lifecycle scripts that run automatically during `npm install`
Typosquatting / Dependency Confusion: Exploiting fake packages with similar names or collisions with internal package names
Abuse of node-gyp / binding.gyp: Exploiting implicit code execution during native builds
Key verified incidents (September 2025)
*The following only includes incidents confirmed by primary sources and multiple security vendors.
Compromise of 18 packages including Chalk / Debug (September 8, 2025)
The account of maintainer "Qix" was hijacked via phishing using a fake 2FA update email (npmjs.help domain), and crypto-clipper malware was injected into 18 packages, including `chalk` (~299 million weekly DLs) and `debug` (~47 million weekly DLs). The total scale exceeded 2 billion downloads per week. The behavior involved overwriting Web3/cryptocurrency transaction destinations in the browser. The malicious versions were removed within hours.Shai-Hulud worm (September 2025)
A self-replicating worm discovered starting from `@ctrl/tinycolor`. It abused postinstall hooks to steal credentials such as npm tokens, GitHub PATs, and cloud keys (AWS/GCP/Azure), and used the stolen credentials to self-propagate to over 500 packages. This is a representative example where "install-time scripts" were the core of the attack.
These attacks cause damage at the time of installation or usage and can contaminate CI/CD pipelines and developer PCs. In particular, techniques that use lifecycle scripts as a foothold, like Shai-Hulud, are the very attack surface that npm v12 is targeting.
2. Changes in npm v12 (Scheduled for release in July 2026)
These are the main changes based on the official GitHub changelog (2026-06-09). All of them change behaviors that "currently run automatically" to "behaviors that require explicit opt-in."
-
`allowScripts` is off by default
→ `preinstall` / `install` / `postinstall` scripts will no longer run automatically unless explicitly permitted in the project. →
Native `node-gyp` builds are also covered: Even for packages that have a `binding.gyp` but no explicit install script, they will be blocked because npm implicitly executes `node-gyp rebuild`. → `prepare` scripts for git / file / link dependencies are blocked as well.
`--allow-git` defaults to `none`
→ Git dependencies, whether direct or transitive, will no longer be resolved without explicit permission (`--allow-git`). This is to close a code execution path where a Git-dependent `.npmrc` could overwrite Git executables even when using `--ignore-scripts`. (Available from npm 11.10.0, announced on 2026-02-18)`--allow-remote` defaults to `none`
→ Dependency resolution from remote URLs, such as https tarballs, will no longer be possible without explicit permission (`--allow-remote`). (Available from npm 11.15.0)
→ Note that the defaults for `--allow-file` / `--allow-directory` will not change in v12.
These changes can already be confirmed as warnings in npm 11.16.0 and later, allowing for preparation before upgrading.
3. Affected Projects
Native modules: `sharp`, `bcrypt`, `canvas`, various DB drivers, etc. (those that use scripts/`node-gyp` during build)
Tools: Cypress, Playwright, Puppeteer, Electron, Husky, etc., which fetch binaries or perform setup in postinstall
Projects with many dependencies in general: CLI tools, agent-based systems, large-scale frontend apps, etc. Environments with many indirect dependencies require caution as more "pending scripts" will appear.
4. Immediate Actions to Take (Preparation Steps)
Upgrade npm to 11.16.0 or higher
Run `npm install` as usual → Check the displayed warnings
Commit the generated allowlist (written to `package.json`) to Git
Ensure the same `package.json` allowlist is applied in CI/CD (using `npm ci` is recommended)
pnpm users already have similar strict controls (build permission system via `onlyBuiltDependencies`), so the transition in mindset should be smooth.
5. Additional Defensive Measures (Best Practices)
Socket / StepSecurity / Dependabot, etc., to continuously audit packages and dependencies
Make `npm audit` and strict lockfile reviews a habit
Use `--ignore-scripts` or sandbox environments in CI
Separate `devDependencies` and maintain a least-privilege dependency configuration
Strengthen npm account 2FA and utilize Trusted Publishing
Utilizing `min-release-age`: npm has introduced a setting to "reject versions published less than a specified number of days ago." This reduces the risk of being caught by malicious versions immediately after they are published.
Conclusion
npm v12 is a major step toward being "secure by default." While attacks will not disappear entirely, you can significantly reduce the blast radius. The important thing is to check `npm install` warnings now before the release and prepare an allowlist of trusted scripts.
If you have any requests such as "which dependencies in my project are likely to be affected," "I want help creating an allowlist," or "I want additional topics like a comparison with pnpm," please leave a comment.
References
Official GitHub Changelog: Upcoming breaking changes for npm v12
The Hacker News: GitHub to Disable npm Install Scripts by Default to Stop Supply Chain Attacks
Explanation of Chalk/Debug compromise (Semgrep): chalk, debug and color on npm compromised
Explanation of Shai-Hulud worm (Unit 42 / Palo Alto Networks): “Shai-Hulud” Worm Compromises npm Ecosystem
Official npm documentation: `npm approve-scripts` / `npm deny-scripts`
いいなと思ったら応援しよう!
サーバー代とコーヒー代になります☕ 役に立ったら応援よろしくお願いします!