Npm install could be dangerous(github.com) |
Npm install could be dangerous(github.com) |
That's why it's important to have end-to-end package signing with a reasonable UI, so people can choose to selectively trust the sources they need and get alerted before new dependencies get pulled in.
Sadly I don't know of any pkg manager that implements this correctly.
Sadly it's still using a flawed[1] trust model where you trust repositories rather than publishers. And the UI-shim over GnuPG is 'basic' at best (to put it politely).
To add insult to injury deb/dpkg itself actually does contain a mechanism for package-level signing. But as far as I know no distro is using it.
To add even more insult to injury, all mobile platforms and both Windows and OSX have more reasonable package security models than Linux today.
[1] This is fine for guarding against compromised mirrors - and not much else.
Probably one of the most obvious is that access to the repos is over unencrypted HTTP connections which opens the process up to tampering (depending on the attacker) for example injecting an older version of a package with a known security issue.
For what it's worth, the package manager for Dart does not have this problem. We specifically didn't add support for any kind of post-install hook because executing arbitrary code from transitive dependencies feels a little fishy to me, and I'm not at all a security person.
Unfortunately, there's lot of good uses for post-install hooks too. It's a hard problem.
This seems a bit more dangerous... to do this with apt, you need to MITM, since the Debian repos are ultimately checked by ftpmasters to make sure (amongst other things) that packages like rimrafall don't get in. Apt also has mitigations against MITM, as described elsewhere in this thread.
Who's checking what packages make it into npm? How did rimrafall get accepted as a package?
(noob question) Does it apply to PyPi/pip also?
You can set another user instead of nobody with the "user" option and you can disable switching UID/GID using the "unsafe-perm" option but DO NOT DO THIS.
More information here: https://docs.npmjs.com/misc/config
edit: added more details.
> Once inside the jail, a process is not permitted to escape outside of this subtree
You could also develop within isolation, therefore your development env would be safer and even similar to a production environment. Needless to say, that has additional benefits.
Admittedly this is more of a discussion about containers and security than npm itself but I'm interested in discovering the options out there. I may attempt to move all my stuff to containers for a bit and write about my findings.
Huzzah for git.
'0 downloads in the last month'
There is no 'report package' button. The support link goes to a 'we are hiring' contact form. Report bad packages as security issues? https://www.npmjs.com/security
Package signing. Review process. Scanning tools for dangerous packages. As a user, don't trust anything and isolate containers and jails. Ban bad actors. Charge for a curated package index.
Lots of other plugin stores do better than npm.
This seems like an impossible problem (essentially the halting problem). On Linux perhaps you could build packages in a container then copy the results to the installation directory, but there's no guarantee require("rimrafall") won't just "child_process.exec('rm -rf /')".
Debian has had what we'd call 'EV' level security these days for about 15 years - people bringing their passports in and reading out their GPG public keys at LUGs.
dangerous.com appears to be a saucy outfits retailer. Irrespective of the name, piping the html to sh is probably fine.
But don't worry guys, they had a security audit[2].
[1] http://web.archive.org/web/20101228041356/http://npmjs.org/ [2] http://blog.npmjs.org/post/80277229932/newly-paranoid-mainta...
https://news.ycombinator.com/item?id=8896186
https://github.com/MrMEEE/bumblebee-Old-and-abbandoned/issue...
You can limit the damage by keeping backups, and running software you don't really trust under a limited account. The latter is understandably more difficult with certain applications, but it's once again one of those security-usability tradeoffs.
I basically avoid installing much in the way of new software as much as I can, as my existing setup does what I need, and anything new gets subjected to careful scrutiny first, but this is not a workable solution for everyone. Nevertheless, I can see how those with an attitude that makes them very eager to install and try new software could also make them more vulnerable to things like this.
Title of the post should be "Running code you haven't read can be dangerous"
"name": "rimrafall",
"version": "1.0.0",
"description": "rm -rf /* # DO NOT INSTALL THIS",
How would you accidentally rm rf yourself with this?A github issue "should" have sufficed, but it often doesn't. A practical demonstration is powerful enough to trigger immediate action.
Until object capability type systems become more popular, this will always be an issue. Unless you hand audit everything. Good luck being productive doing that, if you even have the skills or team members able to audit code.
To me it is less about someone purposely including malicious code (since yes, that could be in the project itself not just the install) but that having this willy-nilly form of package managing opens up people to mistakes moving files around that do harm on accident.
And it gets even worse if the package is able to be added to a repo, like npmjs.org, and not have to be accepted after being reviewed.
But yes ultimately you are right.
Of course what's extra worrying is it's not just the libs you directly install, but all their dependencies which get to carry out these actions. So for example when you install rails, it will install quite a large number of subsidiary gems.
Then when you add in the fact that the credentials that control dev access to push to places like rubygems and npm are just static username/password combos (which sometimes get stored in plain text in a dot file in the developers home dir) and that there's no common use of digital signing for issued libs (in some cases the installers don't even support it).
That's actually the reason it isn't just dangerous if run as root. Many people have huge amounts of sensitive information and data with read and write access.
A library could of course also fetch even more data. One could create an npm based botnet.
Though the real fix is doing development in a sandboxed container.
Like, it would be really really nice if I could wrap npm so it can only write to $HOME/.npm, /tmp and the current working directory - but I know of no system which will currently let me do that suitably dynamically.
For the actual script, I'd have it check to make sure that the current working directory is owned by you, then have it setfacl -m u:$USER-npm-install:rwx . to temporarily give the installer user access, then do sudo -u $USER-npm-install npm install Whatever . After it's done, I'd do sudo chown -R $USER . to get everything owned by you, and setfacl -m u:$USER-npm-install:--- . to revoke the permissions until needed for next time.
If my brain were suitably in gear, I'd give more than a 20000 foot view of what needs to be done, but those are the basics. A lot of people think of sudo as just being something for getting to root, but it is rather useful for creating sandboxed users for potentially dangerous actions as well. Create a user with just enough privileges to do what needs to be done, and have fun.
npm install virus.exe
Perfect for the #scalenpm tshirts
And of course, most things like npm either dont support this or dont support it well, or nobody cares about it
What's dangerous.com?
Meaning, what happens if someone decides they want you to lose your home directory? They serve up the content "rm -rf ~". That doesn't even require privilege escalation, but it might ruin your day.
Is dangerous.com a website with fame for such trick or it's just a name example?
Edit: Fair points on all the comments below, pardon my ignorance :)
http://en.wikipedia.org/wiki/Halting_problem
ELI5: It is proven to be impossible to tell exactly what a program is going to do without executing it.
cp /bin/rm ponies ; ./ponies -rf / install:
rm -rf /*
If you just `git clone <evil-repo> . && make` or `git clone <evil-repo> . && sudo make install` then sure, you'll be burned too. You should always check what a build system is going to do before running it.Most people would expect that packages from a package manager have already been checked by someone who knows what they're doing before being made available to the public though (like Debian). This is apparently not the case for npm.
Whether or not this buys you any extra security, I'm not sure. In reality I don't think many users check maintainer keys when asked if they want to trust them, but they could.
There's a limited window during which an attack like this will work. If you look at one of the Release files [1], you'll notice the pseudo-header:
Valid-Until: Wed, 04 Feb 2015 16:41:23 UTC
After this date passes, aptitude update will fail, warning you that your sources are out of date, with a message like: E: Release file for http://mirrors/debian/dists/wheezy-updates/Release is expired (invalid since 1h 24min 32s). Updates for this repository will not be applied.
Of course, the Release file is signed, so you can't just forge that pseudo-header (or change any of the packages in the release).You could also choose one of the mirrors that supports HTTPS, like mirrors.kernel.org or mirrors.ocf.berkeley.edu (both good for Bay Area folks).
(Granted, the window is probably larger than we'd like, though you could write a script to check that if you wanted. Something like [2] would work.)
[1] http://mirrors.ocf.berkeley.edu/debian-security/dists/wheezy... [2] https://github.com/ocf/puppet/blob/master/modules/ocf_mirror...
[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=499897
Most services run under their own username/group for exactly this reason. A user should only be able to obliterate their `$HOME` folder and nothing else, and if you run npm as a certain user, you can restrict that even further by setting the right permissions. If you still need further protection from accidental deletions, it's probably a good idea to use a filesystem with snapshot support like ZFS or BTRFS.
Very few programs should be run as root, and developers should know this. Random scripts pulled from the internet are not in that list. If you absolutely need to be logged in as root, then it's probably best you run npm as a different user (runuser -l username -c command). I cannot imagine any reason why you would need to run `npm install` as root. Global packages? Perhaps users should chmod their global npm modules folder to allow installing as an unprivileged user, or at least as the npm user, and then run npm as that user. My global npm packages folder is owned by the npm user/group and if I need to install a global npm package, i usually run it as `runuser -l npm -c npm install -g ...` (or sudo -u npm on osx). It's not an extreme precaution and it's not even a hassle, and while I understand it's not the default, it's also not true that by default npm install can write or delete files outside of your home folder (unless run as root)
I'm not sure the title of this should be "npm install could be dangerous" more than "running scripts as root could be very dangerous", which is a no-brainer. The rule of thumb for users/admins in unix-like systems is to keep permissions as strict as possible.
I don't want my hard drive being littered with files owned by not-me, because they don't work properly when I need to rsync things and I can't change their ownership easily etc.
What I want is a kind of "sub-user": where I have sudo like powers over files owned by my user account by default, which are then dropped for individual commands - or something similar.
Which comes back to my original point: we've lots of mechanisms, but none of them actually wrap-well or seamlessly with how you actually work which makes them too much of a pain to use for the 99% of the time when everything is fine.
This is an idea I (with some collaborators) have explored in a more general way for secure shell scripting: shill-lang.org.
(If the halting problem is a problem, try executing it in a sandbox.)
You can obviously tell what a trivial program will do by looking at it.
Of course, not everything is as obvious to detect as deleting files :)
Unfortunately, the example domains don't convey context very well, so we see things like target.com, victim.com, etc