rfcs
rfcs copied to clipboard
[RRFC] npm install uses system-wide node installation instead of local one
I was told to move this here. Previous issue: https://github.com/npm/cli/issues/4390
Version
17.4.0
Platform
Windows x64
Subsystem
No response
What steps will reproduce the bug?
- Download node installation from here: https://nodejs.org/download/release/latest-v17.x/
- Unpack the zip/tar somewhere
- Create a new empty folder and open a terminal in that folder
- Enter the following command in that terminal:
<npm-path> install puppeteer(can be any module, puppeteer just a random example, also the npm-path must be pointing to the npm file from the unpacked node installation from before) - Voila.
How often does it reproduce? Is there a required condition?
NodeJS must NOT be installed system-wide.
What is the expected behavior?
It should check for an existing node.exe in its installation directory first, and only use the global node variable if there is no node.exe in its installation directory.
What do you see instead?
...
npm ERR! path C:\WORK\node_modules\puppeteer
npm ERR! command failed
npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c node install.js
...
As you can see npm tries to execute the command node install.js, the problem is, that node was not installed system-wide and thus there is no global node variable available.
If it’s not available on the command line in the PATH, how can it be found? The current directory isn’t typically part of the PATH on non-windows systems.
This seems like a pretty significant security concern. If I clone a repo and run npm install it'll run any node.exe that happens to be in there?
Also, this decision is pretty intentional. It ensures that the same node is used for all subsequent operations, as other scripts shell out and could potentially run node too.
No. If you run npm install that will use the system wide nodejs installation like it should and currently does.
If you however use something like this C:\Users\Desktop\nodejs-latest\npm install it should NOT use the system-wide node js installation, but the one in C:\Users\Desktop\nodejs-latest\.
Hope this clarifies it.
Ok yes that kind of thing was what was explicitly not supported, for reasons stated previously. If something else runs node it has no way of knowing that you started the process w/ another node.exe. The only way to be certain the same version of node is ran is to let the operating system decide every time.
But what if nodejs isnt installed system-wide? Then C:\Users\Desktop\nodejs-latest\npm install won't work. Which is exactly what one of my users is experiencing.
If you need some other node.exe to take precedence, you should prepend the directory it lives in to your PATH environment variable. Even if you scope this to your current shell or call to npm/node that PATH will be inherited by subsequent shell calls.
@ljharb I assumed the process knows from where it gets executed.
@wraithgar Can you elaborate on the security risk. Because I am unable to see a security risk in my approach on fixing this flaw.
Note that this issue also means that the binary version of node js (.zip) is not fully functional.
The security risk was in running node.exe from the cwd, which is not what you are suggesting.
The binary version of node.js is fully functional, but it has to be installed. Being installed doesn't necessarily mean it lives in a system-level folder, but it does mean that it is accessible via the PATH environment variable. The node.js binary installation docs point this out, it is a prerequisite.
In my case however, I would not want to change the user's PATH variable thus I am suggesting this approach.
That's why you use set instead of setx. set only changes it for the current shell context, not globally.
Going to give that a try and see if it works. Thanks!