Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Excuse me, but what the fuck?

Looks like the line responsible checks if the npm binary is run as sudo and then uses the UID and GID of the invoking user when chowning the directory. [ https://github.com/npm/npm/blob/latest/lib/utils/correct-mkd... ]

I feel like screaming, who thought this was a good idea? If I invoke something as sudo, why does anyone think it should try to detect that and do anything about it? I want to run as the user sudo has set, not my own user, OBVIOUSLY.

Don't try to be smart about sudo, you will break stuff.



The entire JS ecosystem is a case study in trying to be too clever on a well-solved problem.


That's an emergent property, a complex behaviour of a collective arising from interactions at scale, and is presumably an unintended consequence. What interests me is whether this arose by chance, or from some aspect of language design and/or ecosystem initial conditions and subsequent context.


Honestly, I feel this would happen to most systems that have the following properties:

- One size fits all, (clients can only run one language, JS, so it has to fit many use cases).

- Popular (JS seems to be the most popular language at the moment, having beaten Java on most scales in the past year).

- Not owned by a corporation, (whilst probably a good thing, this does lead to "design by committee" issues.

- Backwards compatible (in all this time, only a minimal amount of breaking changes).


Of course. Try running npm on a shared fs (fusehgfs). Most things don't work. This is just shit software and the people who make it need to concern themselves with fixing their software rather than trying to prevent imaginary security problems they shouldn't be trying to prevent anyway (I don't know what their security delusions are exactly, but I do know they are delusions). I'm an engineer and a sysadmin and I I know when something should be run as root or not. That should be my choice and my choice alone. I shouldn't be nagged about it and I certainly shouldn't be prevented. But this is npm. That's why people created yarn, I think.


I completely agree with you.

But in fairness, I can't count the number of times that I've needed to fix things after people treated `sudo npm` as Simon Says[1].

I'm sure they struggled a lot with that issue before coming to this solution. Was it the right solution? Absolutely not. But that's not the point I'm trying to make.

It's all too easy to tunnel vision on a particular solution. I've done it plenty of times, and I'm thankful to those who have helped me to see other alternatives in time.

[1]: https://xkcd.com/149/


One would be forgiven to think that npm run as root would install packages to a system wide location, where multiple applications may utilize them without having write privileges to its code. That what pretty much every other package manager does. Not hose your system and irreversibly render it inaccessible.


I think the easy solution here would be to disable global installs. Pip does that same stuff and it also is known to get people's computers into quite advanced states.

Ideally npm should simply setup a dedicated directory in /opt or /usr/local/ (ie, /usr/local/node/bin or /opt/node/bin) in which it dumps all the global stuff. That way you can easily set permissions for a user and/or contain any damages to that folder. If npm blows up that way it doesn't murder the entire system, you'll still be able to SSH in. (That is unless you use a SSH agent based on node.js in which case; "why?")

Once npm has implemented such a location it should refuse to run with sudo and demand the user setup the correct permissions within the node folder (maybe setup a group "npm-manage" during install?)


> easy solution here would be to disable global installs

I think that's not optimal. Having package being installed "globally" (as in available on your PATH) is nice. You can install `yarn` by doing `npm install --global yarn`.

The trouble is how people setup their node/npm installation. Instead of having global packages setup under the home directory, people use the default which requires root access.

Instead, default installation should be in user-accessible place and running npm with sudo should be exiting without doing anything.


> The trouble is how people setup their node/npm installation. Instead of having global packages setup under the home directory, people use the default which requires root access.

No, like you say in your next sentence the trouble is that it's default. This is NPM's fault, not the user.


I don't get what is the issue on requiring a "global" installation to be added to $PATH, a lot of other tools ask for that during installation and it's by far the safest way to do it.


I basically want what you mentioned later but also available to other users.

Home folder installation only works when you A) only want to install for a user B) the user you run under exists on disk and has a home folder and C) the user can be setup to perform updates.

A lot of the time I run tools that will run as a service. The user it runs under might not have a home folder, probably not even a login or shell. I still need access to the tool installed as root and as normal user for maintenance.

So ideally, I add the path into /etc/profile and install the stuff into /usr/local/node/bin where it is perfectly isolated from the rest of the system.


I think you're saying the same thing. Later in his comment, he mentions installing "global" stuff to `/usr/local/node/bin` or something like that, which is easy to add to your PATH (and can be scripted / documented to be easy to set up). Essentially do what homebrew does, which never seems to run into problems and IIRC completely refuses to run as root nowadays.


It seems not to be entirely without problems, or at least hassle: https://stackoverflow.com/questions/41840479/how-to-use-home...


I don't remember exactly what tool does this, but one package manager (can be homebrew but long time ago I used homebrew) warns users if you are running it as root, since it should install packages as the user.

I think npm could implement a similar strategy and educate the users how packages should really be installed.


Homebrew it is!

$ sudo brew

Error: Running Homebrew as root is extremely dangerous and no longer supported. As Homebrew does not drop privileges on installation you would be giving all build scripts full access to your system.


I really like that message. It used to be something diffr\erent, which was vague, but this actually tells you why it refuses to run as root.


Bundler does something similar - it complains if you run the command with sudo.

Ignoring the warning can result in exciting permissions errors later, which is what I'm guessing the NPM code is trying to avoid.


Several Arch Linux AUR helpers (pacaur and trizen, for example) refuse to run as root. Instead, they invoke sudo to escalate only during the necessary phases.


That's because makepkg rightly refuses to run as root.

    ==> ERROR: Running makepkg as root is not allowed as it can cause permanent,
    catastrophic damage to your system.


mpirun will also throw an error if run as root:

--------------------------------------------------------------------------

mpirun has detected an attempt to run as root. Running at root is strongly discouraged as any mistake (e.g., in defining TMPDIR) or bug can result in catastrophic damage to the OS file system, leaving your system in an unusable state.

You can override this protection by adding the --allow-run-as-root option to your cmd line. However, we reiterate our strong advice against doing so - please do so at your own risk.

--------------------------------------------------------------------------


npm first needs to fix the issue that by default, if you want to do anything globally, you have to use sudo. Homebrew warns against using sudo, but it's also possible to install things globally without using sudo.


I confess, I've resorted to `sudo npm` in a desperate attempt to get something to work at all, when trying to install frontend assets and not being able to make sense of the errors or get a helpful answer out of the frontend team.


Why is such code even necessary??


I'd go further and say that chown should be "considered harmful".

There are 3 use cases I can think for chown(2):

- Implementing the chown command (or other tools whose purpose is explicitly and only to manage permissions)

- Implementing a file copy/archive command that preserves permissions

- For package managers that set up a daemon user for a package, and want to set up the a writable area of the fs for use by that user

In other words, the ownership of files is something that should be totally up to the user, and not something implicitly done by a tool on their behalf.

I can't think of a single other place where trying to automatically manage file ownership is warranted. Files I touch should be owned by me, files root touches should be owned by root, and the correct way to make sure new files are not owned by root is to not be root. Doing literally anything else with chown is being overly clever and is a guaranteed landmine.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: