
GitHub has announced what it described as "breaking changes" arriving in npm version 12, including a default disabling of install scripts as a measure against software supply chain threats.
These updates target attack methods that exploit the "npm install" command to execute malicious code through npm lifecycle hooks. The "npm install" function is used to download and install all required dependencies for a Node.js project. Version 12 is slated for release next month.
Calling install-time lifecycle scripts the "single largest code-execution surface in the npm ecosystem," GitHub noted that the "npm install" command runs scripts from every transitive dependency, meaning a single compromised package anywhere in the dependency tree can execute arbitrary code on a developer machine or CI runner.
By preventing such behavior, the goal is to require explicit user approval before code execution begins automatically during "npm install," rather than being trusted by default. "Making script execution opt-in closes that path while keeping it one command away for the packages you trust," GitHub stated.
The changes are as follows -
npm install will no longer run preinstall, install, or postinstall scripts from dependencies unless they are explicitly permitted in the project.
npm install will no longer resolve Git dependencies, whether direct or transitive, unless explicitly allowed via --allow-git.
npm install will no longer resolve dependencies from remote URLs, such as https tarballs, unless explicitly allowed via --allow-remote.
"This includes native node-gyp builds (i.e., a package with a binding.gyp and no explicit install script still gets blocked, because npm runs an implicit node-gyp rebuild for it)," the Microsoft-owned subsidiary said regarding the default "allowScripts" behavior. "prepare scripts from git, file, and link dependencies are blocked the same way."
By setting "--allow-git" to "none" by default, the measure closes a code execution path where a Git dependency's .npmrc configuration file could override the Git executable, even with --ignore-scripts, a flag that prevents packages listed in a package.json file from automatically running built-in lifecycle scripts during installation.
GitHub advises developers to prepare for these changes by upgrading to npm 11.16.0 or newer, running the normal install, and reviewing the displayed warnings.
"Use npm approve-scripts --allow-scripts-pending to see which packages have scripts, approve the ones you trust, and commit the updated package.json," it added. "After that, only the scripts you approved keep running once you upgrade. Anything you leave unapproved will stop."
Earlier this year, npm also introduced "min-release-age," a setting that instructs npm to reject any package version published less than a specified number of days as a safeguard against newly published malicious packages.