PROBABLYPWNED
AnnouncementsJune 12, 20264 min read

npm v12 Disables Install Scripts by Default to Block Supply Chain Attacks

GitHub announces breaking changes for npm 12 releasing next month. Install scripts, Git dependencies, and remote URLs now require explicit approval to combat malicious packages.

David Okonkwo

GitHub has announced that npm version 12, scheduled for release next month, will disable install scripts by default. The change closes what GitHub describes as the "single largest code-execution surface in the npm ecosystem"—the automatic execution of scripts during package installation that attackers have exploited repeatedly in supply chain attacks.

The update also restricts Git dependencies and remote URL packages, both of which require explicit approval to resolve.

What's Changing

Three significant restrictions take effect in npm v12:

Install Scripts: The npm install command will no longer execute preinstall, install, or postinstall scripts from dependencies unless explicitly allowed. This includes native node-gyp builds—packages with a binding.gyp file still get blocked because npm runs an implicit rebuild for them.

Git Dependencies: Packages that pull from Git repositories won't resolve without the --allow-git flag. This prevents malicious .npmrc configurations from overriding the Git executable. The npm security documentation covers current script behavior.

Remote URLs: Dependencies from HTTPS tarballs or other remote sources need explicit --allow-remote approval.

Each restriction applies transitively. A single compromised package anywhere in your dependency tree could previously run arbitrary code on developer machines or CI runners. That door is now closed by default.

Why This Matters

Supply chain attacks through npm have become increasingly common. Attackers compromise maintainer accounts, inject malicious code into popular packages, or create typosquatted packages that run payload scripts on installation.

The OpenAI Codex supply chain attack we covered earlier this month demonstrated this exactly—malicious packages masquerading as legitimate tools executed credential theft code during installation. Developers never explicitly ran the malware; npm install did it for them.

GitHub's decision to flip the default from "allow everything" to "allow nothing" shifts the security model fundamentally. Developers must now consciously approve script execution rather than consciously blocking it.

Preparing for the Upgrade

GitHub recommends a staged approach:

  1. Upgrade to npm 11.16.0 now. This version displays warnings for all actions that will break under v12, letting you identify problems before the switch.

  2. Run normal install routines and review warnings. You'll see which packages have scripts that will require approval.

  3. Use npm approve-scripts --allow-scripts-pending to see pending scripts and approve the ones you trust.

  4. Commit the updated package.json. Approved scripts persist in your project configuration.

  5. Test your CI pipelines. Automated builds will fail if they hit unapproved scripts.

Breaking Changes You'll Notice

Some legitimate packages will require approval. Anything that compiles native code (like node-sass or bcrypt) runs node-gyp during installation. You'll need to explicitly approve those builds.

Packages that use postinstall scripts for legitimate purposes—running setup tasks, downloading binaries, or configuring environments—will also need approval.

The friction is intentional. GitHub wants developers to think about what code runs during installation rather than trusting the entire dependency tree blindly. This shift parallels how security teams now approach data breach prevention—verify first, trust second.

CI/CD Impact

Automated environments will feel this change most acutely. CI pipelines that run npm install without additional flags will fail when they encounter unapproved scripts.

Teams should:

  • Audit dependencies before the v12 release
  • Pre-approve trusted packages in package.json
  • Update CI scripts to handle the new behavior
  • Consider using --ignore-scripts in contexts where you're certain no scripts need to run

The Broader Context

This change reflects a maturing approach to supply chain security. For years, the JavaScript ecosystem prioritized convenience over safety. Installing packages was frictionless—and so was getting compromised.

npm v12 introduces friction where it belongs: at the boundary between your codebase and external dependencies. That friction has a cost in developer experience, but the alternative is continuing to treat every npm install as an implicit trust decision across thousands of packages.

The July release gives teams roughly a month to prepare. Use that time to audit your dependencies and establish approval workflows. When v12 lands, you'll want those decisions already made.

Related Articles