{"action":"created","issue":{"url":"https://api.github.com/repos/npm/npm/issues/3849","repository_url":"https://api.github.com/repos/npm/npm","labels_url":"https://api.github.com/repos/npm/npm/issues/3849/labels{/name}","comments_url":"https://api.github.com/repos/npm/npm/issues/3849/comments","events_url":"https://api.github.com/repos/npm/npm/issues/3849/events","html_url":"https://github.com/npm/npm/issues/3849","id":18824083,"number":3849,"title":"Global install file-ownership “nobody” - is this really sane ?","user":{"login":"sjorek","id":954635,"avatar_url":"https://avatars.githubusercontent.com/u/954635?v=3","gravatar_id":"","url":"https://api.github.com/users/sjorek","html_url":"https://github.com/sjorek","followers_url":"https://api.github.com/users/sjorek/followers","following_url":"https://api.github.com/users/sjorek/following{/other_user}","gists_url":"https://api.github.com/users/sjorek/gists{/gist_id}","starred_url":"https://api.github.com/users/sjorek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sjorek/subscriptions","organizations_url":"https://api.github.com/users/sjorek/orgs","repos_url":"https://api.github.com/users/sjorek/repos","events_url":"https://api.github.com/users/sjorek/events{/privacy}","received_events_url":"https://api.github.com/users/sjorek/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/npm/npm/labels/big-bug","name":"big-bug","color":"E03C28"},{"url":"https://api.github.com/repos/npm/npm/labels/bug","name":"bug","color":"A328B3"},{"url":"https://api.github.com/repos/npm/npm/labels/documentation","name":"documentation","color":"5A1991"},{"url":"https://api.github.com/repos/npm/npm/labels/needs-repro","name":"needs-repro","color":"BDFFCA"},{"url":"https://api.github.com/repos/npm/npm/labels/security","name":"security","color":"415D66"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2013-08-31T15:34:28Z","updated_at":"2016-05-12T05:48:47Z","closed_at":null,"body":"I known this is a :boom:-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.\r\n\r\nBut 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! :metal: \r\n\r\nI'll base my assumptions on a quotation from http://en.wikipedia.org/wiki/Nobody_(username) :\r\n\r\n> In many Unix variants, \"nobody\" is the conventional name of a user account which **owns no files**, is in no privileged groups, and has no abilities except those which every other user has.\r\n\r\nThe 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.\r\n\r\nBut first let us continue with the quotation, without drawing any conclusions:\r\n\r\n> It is common to run daemons as nobody, especially servers, in order to limit the damage that could be done by a malicious user who gained control of them. However, **the usefulness of this technique is reduced if more than one daemon is run like this**, because then gaining control of one daemon would provide control of them all.\r\n\r\nThis is only partially true - on modern operating systems proper ACLs, sandboxes, chroots and other security enhancing techniques protect from such weaknesses.\r\n\r\n> The reason is that nobody-owned processes **have the ability to send signals to each other**  and even debug each other, allowing them **to read or even modify each other's memory**.\r\n\r\nThis 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.\r\n\r\n------------\r\n\r\nSo let me sum up the (to my mind) major points, and mark npm's compliance to these assumptions with:\r\n\r\n- :o: ok, npm's global install privileges do not weaken security or\r\n       do not implicitly suffer from weaknesses\r\n- :x: not ok, npm's global install privileges weaken security or\r\n       suffer from weaknesses implicitly\r\n\r\n------------\r\n\r\nPlease, keep in mind, that I struggle with npm's global install behavior - especially with the _nobody_-ownership !\r\n\r\n1. :x: nobody owns no files:\r\n    - npm installs files globally owned by nobody\r\n    - if one decides to run a service as _nobody_ (not very uncommon)\r\n      it can modify everything installed by npm globally\r\n    - If one decides to run more than one service as _nobody_ then filesystem _ACLs_,\r\n      _sandboxes_ or _chroots_ may protect these services from each other, _but\r\n      avoiding nobody-ownership and still let the services run as nobody would be the\r\n      “cheapest” approach_.\r\n\r\n2. :o: nobody does **not** run more than one service\r\n    - npm/node.js does not force any service to run as nobody, it's up to the\r\n      implementation to gain proper privileges\r\n    - Again, if one deliberately runs more than one service as _nobody_, then other\r\n      ways of protecting these services from each other are available, without any\r\n      negative effects but certainly with overhead\r\n    - **Changing global install ownership won't help here, it's up to the implementation**\r\n\r\n3. :x: services running as _nobody_, can **not** tweak other _nobody_-services' signals\r\n    - obviously true. As long as there are no protections build into the services,\r\n      every other service can connect to other services and send IPC signals\r\n    - **Changing global install ownership won't help here, it's up to the implementation**\r\n\r\n4. :o: services running as _nobody_, can **not** tweak other _nobody_-services' memory\r\n    - I don't know any way of accessing memory under _node.js_, that does not\r\n      imply, that there is no way (maybe someone implements a native-module to\r\n      do so)\r\n    - **Changing global install ownership won't help here, it's up to the implementation**\r\n\r\n--------\r\n\r\nMy 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 …\r\n\r\nMy 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.)\r\n\r\n**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!)\r\n\r\nIf 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.\r\n\r\nI really appreciate any feedback - even if so much has already been said and written !\r\n\r\nThanks a lot,\r\nStephan\r\n:speak_no_evil: :hear_no_evil: :see_no_evil:"},"comment":{"url":"https://api.github.com/repos/npm/npm/issues/comments/218665988","html_url":"https://github.com/npm/npm/issues/3849#issuecomment-218665988","issue_url":"https://api.github.com/repos/npm/npm/issues/3849","id":218665988,"user":{"login":"othiym23","id":418097,"avatar_url":"https://avatars.githubusercontent.com/u/418097?v=3","gravatar_id":"","url":"https://api.github.com/users/othiym23","html_url":"https://github.com/othiym23","followers_url":"https://api.github.com/users/othiym23/followers","following_url":"https://api.github.com/users/othiym23/following{/other_user}","gists_url":"https://api.github.com/users/othiym23/gists{/gist_id}","starred_url":"https://api.github.com/users/othiym23/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/othiym23/subscriptions","organizations_url":"https://api.github.com/users/othiym23/orgs","repos_url":"https://api.github.com/users/othiym23/repos","events_url":"https://api.github.com/users/othiym23/events{/privacy}","received_events_url":"https://api.github.com/users/othiym23/received_events","type":"User","site_admin":false},"created_at":"2016-05-12T05:48:47Z","updated_at":"2016-05-12T05:48:47Z","body":"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.\r\n\r\nHowever, 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 [`phantomjs`](http://npm.im/phantomjs) here). A complete solution to this is going to require some care and probably some breaking changes."}}