-
Notifications
You must be signed in to change notification settings - Fork 3k
Global install file-ownership “nobody” - is this really sane ? #3849
Comments
After using the force and digging deeper into the source I found out that
This could mean several things (including those I observed):
So my final conclusions are now:
I appreciate any feedback, |
IMO it is a serious issue that files are installed as |
@zkat and I just spend a good 15 minutes talking through what we believe is going on here, and I ultimately realized that what the code says it's doing doesn't match the description here. npm shouldn't be writing files as |
Yay, finally, someone takes this seriously! The default user is set to 'nobody' in lib/config/defaults.js user: process.platform === 'win32' ? 0 : 'nobody', and the files are extracted as the default user in lib/install/action/extract.js, unless the unsafe-perm is set var up = npm.config.get('unsafe-perm')
var user = up ? null : npm.config.get('user') However, the safe thing would be to write the files as root, and run the files as nobody or some custom npm-user, thus the extract file above should say something like: if(npm.getCurrentUser() == 'nobody') {
fail("running as 'nobody': but 'nobody' lacks permission to write");
} else {
var user = npm.config.global ? root : npm.getCurrentUser()
} basically if running as 'nobody' extract should fail, if running with '-g' it should install as root and if running without '-g' it is being installed locally and should be installed as whoever ran npm. |
It's much more complicated than that, when you start tracing through all of the various code paths that touch permissions and the configuration around user and group. I would like npm to be simpler and safer about how it writes files to disk. However, that's not the end of the story, because the lifecycle permissions affect child processes run by the CLI, which themselves sometimes write files (think |
I admire that. As for the complexity of it, lifecycle.js does it correctly: run subsequent Thus, so long as extract.js does it's job correctly and not extract files The only time a user should run anything as root is during a global install, |
It's getting quite confusing at this stage, I didn't even know about the nobody user before checking the write permissions of these folders. juli@ArchLinux` /usr/lib/node_modules % ls -la
total 244
drwxr-xr-x 22 juli root 4096 Nov 15 23:09 .
drwxr-xr-x 286 root root 159744 Nov 15 13:10 ..
drwxr-xr-x 6 root root 4096 Sep 16 10:29 acorn
drwxr-xr-x 4 nobody juli 4096 Nov 15 22:57 ansi
drwxr-xr-x 7 root root 4096 Nov 15 22:54 browserify
drwxr-xr-x 3 root root 4096 Nov 15 23:09 cordova
drwxr-xr-x 7 nobody juli 4096 Nov 15 22:35 eslint
drwxr-xr-x 6 nobody juli 4096 Nov 13 00:57 generator-code
drwxr-xr-x 4 nobody juli 4096 Nov 13 01:06 generator-electron
drwxr-xr-x 6 nobody juli 4096 Oct 27 14:13 grunt-cli
drwxr-xr-x 6 nobody juli 4096 Nov 15 22:25 gulp
drwxr-xr-x 7 nobody juli 4096 Nov 12 20:46 jshint
drwxr-xr-x 6 nobody root 4096 Nov 15 01:17 nativefier
drwxr-xr-x 7 nobody juli 4096 Nov 15 22:37 node.js
drwxr-xr-x 12 nobody juli 4096 Nov 15 22:49 npm
drwxr-xr-x 6 nobody root 4096 Oct 27 14:12 nw-gyp
drwxr-xr-x 3 root root 4096 Nov 15 23:09 phonegap
drwxr-xr-x 3 root root 4096 Nov 15 23:09 pm2
drwxr-xr-x 3 root root 4096 Jul 15 04:25 semver
drwxr-xr-x 6 root root 4096 Oct 26 03:21 uglify-js
drwxr-xr-x 8 nobody juli 4096 Oct 27 14:13 webpack
drwxr-xr-x 4 nobody juli 4096 Nov 13 01:06 yo This is what I get in the terminal when trying to run a global update: npm ERR! addLocal Could not install /build/acorn/src/acorn-4.0.3.tgz
npm ERR! addLocal Could not install /build/browserify/src/browserify-13.1.1.tgz
npm ERR! addLocal Could not install /build/uglify-js/src/uglify-js-2.7.4.tgz
npm ERR! addLocal Could not install /build/npm/src/npm
npm WARN deprecated [email protected]: ReDoS vulnerability parsing Set-Cookie https://nodesecurity.io/advisories/130
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
/usr/lib
├── [email protected]
└── [email protected]
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/pm2/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm ERR! Linux 4.8.7-1-ARCH
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "-g" "update"
npm ERR! node v7.1.0
npm ERR! npm v3.10.9
npm ERR! path /usr/lib/node_modules/.staging/ansi-a242ced5
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! syscall rename
npm ERR! enoent ENOENT: no such file or directory, rename '/usr/lib/node_modules/.staging/ansi-a242ced5' -> '/usr/lib/node_modules/cordova/node_modules/npm/node_modules/ansi'
npm ERR! enoent ENOENT: no such file or directory, rename '/usr/lib/node_modules/.staging/ansi-a242ced5' -> '/usr/lib/node_modules/cordova/node_modules/npm/node_modules/ansi'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! Please include the following file with any support request:
npm ERR! /home/juli/npm-debug.log
sudo npm -g update 22.03s user 1.85s system 83% cpu 28.508 total
I can also attach the log file if it helps in any way... |
Update: Actually the terminal output I posted previously didn't have an I found this video in the npm docs which really helped, and the solution for me was this:
chown the folder and files recursively Neverthless I hope it helps seeing that I had such a mix up of user ownerships and I am sure it happens often with other people too. Now I just have to figure out a solution to the |
We're closing this issue as it has gone thirty days without activity. In our experience if an issue has gone thirty days without any activity then it's unlikely to be addressed. In the case of bug reports, often the underlying issue will be addressed but finding related issues is quite difficult and often incomplete. If this was a bug report and it is still relevant then we encourage you to open it again as a new issue. If this was a feature request then you should feel free to open it again, or even better open a PR. For more information about our new issue aging policies and why we've instituted them please see our blog post. |
WTF!?! Issues labeled big-bug and/or security should not be auto-closed. That is a huge security bug in and of itself! |
@78juli you have invalid link in your latest post, it should be https://docs.npmjs.com/getting-started/fixing-npm-permissions |
I known this is a 💥-topic, as already seen in the now closed issue https://github.com/isaacs/npm/issues/601 . Nevertheless I'd like to add some thoughts I have missed in the former discussions.
But before I start to dig into this topic, I'd like to mention that I really appreciate the work done in npm as well as node.js. Keep up the good work! 🤘
I'll base my assumptions on a quotation from http://en.wikipedia.org/wiki/Nobody_(username) :
The point I struggle with is: nobody … owns no files. This is true for every fresh installed Linux I've seen so far, as well as all BSDs including OS X. Please, prove me that I'm wrong ! … I'm talking here about real files, not file-descriptors of unix-domain-sockets or linux-devices.
But first let us continue with the quotation, without drawing any conclusions:
This is only partially true - on modern operating systems proper ACLs, sandboxes, chroots and other security enhancing techniques protect from such weaknesses.
This also is partially true - because every daemon (process) is able to use private/protected memory areas isolated from other processes, if security is really a concern and the proper OS provides such techniques.
So let me sum up the (to my mind) major points, and mark npm's compliance to these assumptions with:
do not implicitly suffer from weaknesses
suffer from weaknesses implicitly
Please, keep in mind, that I struggle with npm's global install behavior - especially with the nobody-ownership !
it can modify everything installed by npm globally
sandboxes or chroots may protect these services from each other, but
avoiding nobody-ownership and still let the services run as nobody would be the
“cheapest” approach.
implementation to gain proper privileges
ways of protecting these services from each other are available, without any
negative effects but certainly with overhead
every other service can connect to other services and send IPC signals
imply, that there is no way (maybe someone implements a native-module to
do so)
My personal conclusion: npm is the only tool I know, installing files owned by nobody (globally). This scares me (:ghost:) a little bit - but I have to admit that I have no death-prove way to exploit this fact. Only thoughts …
My personal wish (:gift:) : I'd like to have the chance to configure/override the global install ownership, without touching the process uid/gid of globally running npm-scripts. (Please read my second comment to get a clue what changes I'd like to incorporate.)
Did I overlook something ? Is it already there ? Am I (too) paranoid ? (If yes, yes or yes then I'm really sorry to waste your time!)
If not I'd like to offer a branch to pull (:octocat:), with such an option implemented, but only if you're willing to incorporate such a feature and moreover if we find a common denominator in an upcoming discussion.
I really appreciate any feedback - even if so much has already been said and written !
Thanks a lot,
Stephan
🙊 🙉 🙈
The text was updated successfully, but these errors were encountered: