Motivation ("The Why")
Recent supply chain attacks have spurred many important improvements to the npm CLI, including configuration options that help prevent being the victim of one. However, the npm configuration is not always "user-controlled", which can lead to unexpected (and potentially compromising) outcomes. In particular, a user may have a secure user-level configuration (~/.npmrc) but run a command in a compromised/malicious project and end up in a bad situation. Alternatively, a user may have a secure user-level configuration but have some third-party script unexpectedly run npm install --ignore-scripts=false <malicious-package>1.
For this reason I would propose the npm CLI attempts to prevent such a security-conscious user from being the victim of a supply chain attack by alerting them when this situation arises, or at the very least leave a trace when it happens.
Example
You have a user level configuration
$ cat ~/.npmrc
ignore-scripts=true
min-release-age=7
And you have just cloned an (untrusted) repository with a local configuration file
$ cat random-github-project/.npmrc
ignore-scripts=false
min-release-age=0
If you install dependencies, it won't inform you about the configuration conflicts
$ npm --version
11.12.1
$ npm install # or npm clean-install
added X packages, and audited Y packages in 420ms
found Z vulnerabilities
How
Current Behaviour
The option value in the "closest" configuration wins and is used.
Desired Behaviour
If there is a conflict for an option between configurations (files or CLI) the npm CLI should either
- Prompt the user for confirmation that the configurations are conflicting, and which option value will be used, or
- Output a warning that there was a conflict, or
- Error and not do anything
Where an example of a configuration mismatch is if one explicitly specifies ignore-scripts=false and another one explicitly specifies ignore-scripts=true.
I would personally advocate for using (1) when a TTY is detected and falling back to (2) otherwise, e.g. in CI.
The behavior itself may be configurable, but in that case should only be respected when provided at the user level (~/.npmrc) or CLI.
In some ideal world it should not be considered a problem when, say, the project-level configuration is more strict than the user-level configuration2. However, I imagine it can be difficult and contentious to determine when a configuration is "more strict".
References
Motivation ("The Why")
Recent supply chain attacks have spurred many important improvements to the npm CLI, including configuration options that help prevent being the victim of one. However, the npm configuration is not always "user-controlled", which can lead to unexpected (and potentially compromising) outcomes. In particular, a user may have a secure user-level configuration (
~/.npmrc) but run a command in a compromised/malicious project and end up in a bad situation. Alternatively, a user may have a secure user-level configuration but have some third-party script unexpectedly runnpm install --ignore-scripts=false <malicious-package>1.For this reason I would propose the npm CLI attempts to prevent such a security-conscious user from being the victim of a supply chain attack by alerting them when this situation arises, or at the very least leave a trace when it happens.
Example
You have a user level configuration
$ cat ~/.npmrc ignore-scripts=true min-release-age=7And you have just cloned an (untrusted) repository with a local configuration file
If you install dependencies, it won't inform you about the configuration conflicts
How
Current Behaviour
The option value in the "closest" configuration wins and is used.
Desired Behaviour
If there is a conflict for an option between configurations (files or CLI) the npm CLI should either
Where an example of a configuration mismatch is if one explicitly specifies
ignore-scripts=falseand another one explicitly specifiesignore-scripts=true.I would personally advocate for using (1) when a TTY is detected and falling back to (2) otherwise, e.g. in CI.
The behavior itself may be configurable, but in that case should only be respected when provided at the user level (
~/.npmrc) or CLI.In some ideal world it should not be considered a problem when, say, the project-level configuration is more strict than the user-level configuration2. However, I imagine it can be difficult and contentious to determine when a configuration is "more strict".
References
--min-release-ageon CLI or in the lockfile #856Footnotes
as described in https://lists.archlinux.org/archives/list/aur-general@lists.archlinux.org/thread/L2JXQNYBGWOQQQXDEPEAICBHKFEFANUC/ ↩
For example,
ignore-scripts=falsein~/.npmrcandignore-scripts=trueinproject/.npmrc. ↩