[RRFC] Warn/Prompt/Error for configuration conflicts
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 777
- Forks
- 267
- PR merge metrics
- No merged PRs in 30d
Description
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.
[^1]: as described in https://lists.archlinux.org/archives/list/aur-general@lists.archlinux.org/thread/L2JXQNYBGWOQQQXDEPEAICBHKFEFANUC/
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 configuration[^2]. However, I imagine it can be difficult and contentious to determine when a configuration is "more strict".
[^2]: For example, ignore-scripts=false in ~/.npmrc and ignore-scripts=true in project/.npmrc.
References
- Relates to #856
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Review npm CLI configuration precedence through the npm install and npm clean-install entry points, using ~/.npmrc, project/.npmrc, and CLI options as the cases described here. Done requires a settled behavior for conflicting values, including TTY and CI handling, rather than an open choice among prompting, warning, and erroring.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- cli, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100