11 ms·
Vulnerability #319816 – npm fails to restrict the actions of malicious packages
- ktRolster 11y agoAnd no intention from NPM to fix (according to the article)
- mkagenius 11y agoWhat solution can we propose?
- ktRolster 11y agoThe article suggests this: > >As a user who owns modules you should not stay logged into npm. (Easily enough, npm logout and npmlogin) >Use npm shrinkwrap to lock down your dependencies >Use npminstall someModule --ignore-scripts > I would add to toss a glance at the libraries you import every once in a while. Just to make sure they look sane.
- u223344 11y ago--ignore-scripts won't help much. The act of using any npm module means you implicitly trust all the javascript code in the module and any of its dependencies. Has anyone taken the time to inspect every line of the dozens of modules that many common packages pull in? Not likely.
- paulirish 11y agoNPM could take a few actions. The original disclosure PDF[1] suggests these: ● Automatically expire login tokens ● Require 2 factor auth for publish operations ● Help users be logged out during install operations vjeux mentioned a few others on HN a few days back[2]: ● pre-install/post-install scripts should require user to accept or refuse. ● make shrinkwrap by default (and fix all the issues with it) so that running npm install doesn't use different versions when used over time. ● make updating a version an explicit decision via npm upgrade [1] https://www.kb.cert.org/CERT_WEB/services/vul-notes.nsf/6eacfaeab94596f5852569290066a50b/018dbb99def6980185257f820013f175/$FILE/npmwormdisclosure.pdf https://www.kb.cert.org/CERT_WEB/services/vul-notes.nsf/6eac... [2] https://news.ycombinator.com/item?id=11341145 https://news.ycombinator.com/item?id=11341145 In the meantime, users may want to consider one of the following: npm config set ignore-scripts true npm logout
- mayank 11y agoIt's definitely a nuanced issue. > ● Automatically expire login tokens I don't see how this helps the issue at hand; a worm could spread very quickly, requiring just a single publish from each freshly infected user. > ● Require 2 factor auth for publish operations This seems very reasonable, and the easiest to implement. It also has the nice effect of being a captcha to the publish operation, which gives it some of the gravitas it deserves in an open ecosystem like npm. > ● Help users be logged out during install operations This may break far more packages than might be considered acceptable. > ● pre-install/post-install scripts should require user to accept or refuse. Presumably this would be unnecessary with 2FA for each publish operation. > ● make shrinkwrap by default (and fix all the issues with it) so that running npm install doesn't use different versions when used over time. Doesn't do much to address the issue at hand. A static dependency tree doesn't mean benevolent dependencies. > ● make updating a version an explicit decision via npm upgrade Same issues as shrinkwrap.
- wycats 11y ago>> ● Require 2 factor auth for publish operations > This seems very reasonable, and the easiest to implement. It also has the nice effect of being a captcha to the publish operation, which gives it some of the gravitas it deserves in an open ecosystem like npm. I agree, especially since Google Authenticator makes this pretty easy to implement.
- johannes1234321 11y ago> > ● pre-install/post-install scripts should require user to accept or refuse. > > Presumably this would be unnecessary with 2FA for each publish operation. 2FA still doesn't mean you can trust the install script. Not running scripts automatically gives a chance to audit before they run. And even with 2FA a worm could spread: It could manipulate the local npm installation so whenever you want to upload a package it will modify it during the publishing process giving you a 2nd-factor-request right when you expect it. The only way to prevent that I can come up quickly is to over a chance to verify the package between signing (which npm doesn't support) and publishing.
- mrmondo 11y agoIMO NPM is broken by design, it's too late - time to move on.
- davnn 11y agoI've already written it in another comment: a different way of solving the problem would be to build a tool that allows developers to mark releases as safe. (public lgtm) Every package would have a safety score and you could decide yourself if that's good enough for you.
- userbinator 11y agoI have a feeling that a lot of other systems also provide "the capability for a self-replicating worm", as that's just the nature of computers in general, and part of why they're so very useful. To me, the fact that this "vulnerability" requires explicit user action, akin to deliberately downloading and running malware, says that it's really a property of all software ecosystems in which people can publish and disseminate freely. In that respect, it's nice to see a "this is as intended" response instead of the typical direction of coming up with a set of more draconian policies and processes merely to protect users from themselves. But given what "security research" these days seems to involve, I can almost imagine in the future: "Vulnerability #1048576 - computer allows users to perform potentially malicious actions."
- vjeux 11y agoAs a developer in the node ecosystem, you run npm install multiple times a day. If one of the dependency you require has been infected, it will look for all the packages you own on npm and will publish a new infected version. Now any time another developer that has one of your packages as dependencies does npm install, it will infect that person again. Once it reaches a package like left-pad that is used by a ton of libraries, it will instantly infect hundreds of thousands of developers.
- NathanKP 11y agoSolution: 1) Pin your packages to a specific version. If you aren't doing this already they you are in for a world of hurt when someone who doesn't know what they are doing releases a breaking package change on a minor version number. 2) Shrinkwrap your packages. Once again if you aren't already doing this then you npm install will probably break about once per three months when someone pushes a bad package to NPM. 3) Publish your NPM packages from an NPM in one vagrant development environment and run your code that installs from NPM in another vagrant development environment. If you have one shared environment then you are going to have other issues of which the small chance of an NPM worm is probably going to be the least of your worries.
- 11y ago
- blaisio 11y agoUnless I'm not understanding this correctly, every package manager is vulnerable to this attack (along with many others). I'm not sure why someone bothered to write this down and make an official "disclosure". Maybe someone more knowledgeable can explain? I mean really the idea is just that if someone got somebody else's password, they could use it to trick other people into installing a program. Even email has this problem. So really the only thing NPM could be accused of here is not doing more to make publishing secure (like using two-factor authentication).
- ghayes 11y agoWell, isn't proper authentication a solution in and of itself? Using keys with pass phrases or requiring sudo to publish would theoretically mitigate this issue.
- minitech 11y agoNo, because it can just sit in the background and wait until you type your passphrase at some point. As soon as you run malicious code, it’s all over; no workarounds. It would be nice if npm didn’t run arbitrary install scripts by default…
- BenjaminCoe 11y agoSimilar problems exist in most package management systems. registries that have a manual review process mitigate this danger, but there's still always a risk of malicious code getting into the world. Having said this, we'd like to make exploits such as those discussed in #319816 as difficult as possible. We're exploring supporting new authentication strategies: such as 2-factor authentication, SAML, and asymmetric key based authentication (some of these features are already available in our Enterprise product, but haven't made it to the public registry yet). npm's official response has more details on this subject: http://blog.npmjs.org/post/141702881055/package-install-scripts-vulnerability http://blog.npmjs.org/post/141702881055/package-install-scri...
- raesene3 11y ago
- en4bz 11y agoDoes npm require signing of packages?
- raesene3 11y agonope and not only that it's not even supported AFAIK
- diegorbaquero 11y agoNow that things like GreenKeeper exists, the ^ should be removed from being a default thing.
- jessaustin 11y agoYes, but that should be done in a patch update, so all the semver extremists can ignore the semver violation like they did the first time when "~" was switched to "^": https://github.com/npm/npm/releases/tag/v1.4.3 https://github.com/npm/npm/releases/tag/v1.4.3 (note the "3" at the end, instead of "0")
- spankalee 11y agoAutomatically running pre and post scripts is absolutely insane.
- msoad 11y agoYes, with that you don't even need to "socially fool the package owner". You can use common misspelling for famous packages. It gets you very far. For example "lowdash" instead of lodash.
- insin 11y agoI wonder if npm has metrics for this - how many times a month are people attempting to "npm install boostrap"?
- wycats 11y agoAll package managers (that I know of) for dynamic languages offer a mechanism for compiling native code for packages that include bindings to C libraries. That mechanism could easily be used to achieve the same goal, even if there was no explicit "post-script" mechanism.
- derefr 11y agoDebian solved this particular problem a long time ago, with pbuilder(1): packages that are installed "from source" simply get compiled in a chroot. Strangely, nobody has ever copied the idea. The modern hipster-language equivalent would probably be to make the package manager depend on the presence of Docker/rkt/systemd, and use it to pull down a dev-env container and build the native bindings in that.
- regularfry 11y agoDon't give them ideas!
- ambrop7 11y agoNix/NixOS - everything is build not only in a chroot, but also in various namespaces. Of course that doesn't help if you actually use a package (directly or indirectly) hence executing it outside of the build chroot.
- msoad 11y ago> 1. Socially engineer a npm module owner... Social engineering is not accepted in many security bounties. Just saying...
- dkopi 11y agoIt's a good thing the bad guys don't use social engineering either.
- deleted 11y ago[deleted]
- notdonspaulding 11y ago"It rather involved being on the other side of this airtight hatchway" https://blogs.msdn.microsoft.com/oldnewthing/20060508-22/?p=31283 https://blogs.msdn.microsoft.com/oldnewthing/20060508-22/?p=...
- myhf 11y agoThis is not the first time I've seen that argument used to justify ignoring persistence attacks.
- chromakode 11y agoIn development, you should separate your npm publish credentials from your dev execution environment. Use some kind of sandbox where you `npm install` -- a VM is best. In production, you should review the packages in your dependency tree and ensure that the exact version you reviewed is what you deploy. To that end, you should shrinkwrap your dependencies. Vendoring works well too. Shameless plug: for additional strictness in your shrinkwrap, you can use https://github.com/chromakode/exactly https://github.com/chromakode/exactly to store content hashes.
- yoklov 11y agoDo people do this? It sounds unmanageable, especially if you publish packages depending on other packages.
- kibwen 11y ago> npm encourages the use of semver, or semantic > versioning. With semver, dependencies are not locked to > a certain version by default. For any dependency of a > package, the dependency author can push a new version of > the package. I don't see how this has anything to do with semver. Semver doesn't say anything about not locking dependencies to a certain version (i.e., locking to a specific version is totally legal), nor does it have anything to do with allowing package authors to push new versions of their packages (I'm not even sure how to parse this sentence, really... should it be impossible to ever push new versions of a package? (EDIT: maybe it's suggesting there should be a central review process, like the iOS App Store?)). In fact, the semver spec doesn't even advocate automatically upgrading when new patch versions are released: "As a responsible developer you will, of course, want to verify that any package upgrades function as advertised. The real world is a messy place; there’s nothing we can do about that but be vigilant." http://semver.org/#why-use-semantic-versioning http://semver.org/#why-use-semantic-versioning
- tatterdemalion 11y agoI think that semver encourages unaudited updates by acting as a substitute for auditing in practice. Obviously the spec doesn't say that you should blindly accept all bugfix updates, but in practice many people do. I often do.
- davnn 11y agoEveryone does and I don't think we will be able to change that. It would be nice if there would be a tool that would allow developers to mark a new release as safe. Every package would have it's social safety score and you could decide if you want to investigate a release further.
- jrochkind1 11y agoWhat do you mean by 'safe'? There is such a tool built-into semver -- it's releasing with a patch or minor version bump! Which means it should be entirely backwards compatible with the previous release. Do you mean something else by 'safe'? I think the issue parent is worried about is if you can't trust the author's declaration of safety.
- foota 11y agoIt does seem to me like it would be reasonable enough to not have npm stay logged in after running a command.
- raesene3 11y agoKind of amusing that this is considered to need a new vuln. report, I kind of assumed it was common knowledge. Most of the programming language package repositories (e.g. npm, rubygems, PyPi, NuGet) have this kind of installation process and limited/no checks for malicious content. Also as there's no consistent use of package signing by the developer (it's either unsupported or not very used) there is also a risk of the repository itself being compromised. I did a talk last year for OWASP AppSecEU that covers this kind of thing. https://www.youtube.com/watch?v=Wn190b4EJWk https://www.youtube.com/watch?v=Wn190b4EJWk
- semi-extrinsic 11y agoA very insightful look at package signing, and why it wouldn't actually improve security for PyPI, by Python packaging guru Donald Stufft: https://caremad.io/2013/07/packaging-signing-not-holy-grail/ https://caremad.io/2013/07/packaging-signing-not-holy-grail/
- raesene3 11y agoIndeed package signing is not the holy grail and won't solve all problems, but it is a part of a secure system. For the problem this blog post talks about, I personally think that keybase is the right solution. You can tie a key to a github repository amongst others and then validate that the package you're installing came from the person who put the code on github in the first place...
- jessaustin 11y agoWhat a great link: topical and well-reasoned! The concluding sentence is interesting: "My biggest hope is that we’ll get a solution where the end user has the relationship with the source of trust and not the package author." If one runs one's own npm registry and audits everything that goes into it, one can have that already with npm.
- semi-extrinsic 11y agoYes, that closing remark is very interesting. It would essentially be formalising what we somehow do manually/instinctively today: "Installing numpy/react/etc.? Yes, everyone I know trusts that, so I do too." "Installing random small non-popular package? I better have a bit of a look at the code first."
- deleted 11y ago[deleted]
- inglor 11y agoIt's disappointing to see you post this Sebastian, sure - Babel was affected by the whole left-pad ordeal but is more drama what would really help right now? You're a doer - if you want to see something done about it at Facebook no one is stopping you from forking NPM or contributing code to it.
- fibo 11y agoJust to share, there is an issue about uglifyjs https://github.com/mishoo/UglifyJS2/issues/936 https://github.com/mishoo/UglifyJS2/issues/936
- nailer 11y agoThe uglify authors should use 'uglify' per the naming conventions and can easily reserve uglify-js and uglifyjs as empty / legacy packages.
- u223344 11y agoAccording to the parent link they've been waiting for npm support to respond for a over a month.
- u223344 11y agoIronically the same person who first reported this npm vulnerability used the wrong package name uglifyjs instead of uglify-js in an unrelated github project. https://github.com/mishoo/UglifyJS2/issues/936#issuecomment-179910332 https://github.com/mishoo/UglifyJS2/issues/936#issuecomment-... https://github.com/samccone/The-cost-of-transpiling-es2015-in-2016/issues/27 https://github.com/samccone/The-cost-of-transpiling-es2015-i... Or perhaps was it a security experiment to see how long it took someone to notice.
- pfooti 11y agoI feel like, with the left-pad fiasco, the node dev world (and the broader programmer community) is rediscovering the web of trust that makes open source feasible. I mean, if I distributed a library through some other package manager system, like a .jar file or some code that you install via homebrew, pip, or ./configure.sh && make, I can embed malicious code in the source somewhere. Maybe not all automated package managers are quite as vulnerable to install hooks, but all open source code is vulnerable to trust attacks, at runtime if nowhere else. I ultimately trust the process that gives me nginx enough to let it serve up my code, hoping there's not a backdoor somewhere that is shoving environment variables (and therefore API keys) out the window to a hacker. You can't assume people are going to review every line of source before they link against a library. You can't assume people aren't going to click that link that looks like a download link on a sourceforge page but is, in fact, a crapware link. People make mistakes all the time. So, yeah, there's probably room to make npm a little more robust and difficult to specifically target as a vector. But thousands of developers are still going to be writing sass, and using node-sass to build that, which needs to download, compile and execute a binary on the devbox. Making the installation process of libsass take an extra step or two is great and all (and annoying, and probably likely to degrade windows node development most of all, since windows libraries are harder to put in a "standard" place if you're a non-windows dev writing a node library), but people are still going to be running libsass binaries on their local machine without auditing it, trusting that the developers there have good opsec and review everything well. On the other hand, all this publicity means someone's bound to actually try and build stuff that exploits trust here, either wormlike or just executing an rm -rf in an install hook. So, my trust levels are lowered and my productivity impaired because I'll be auditing more closely all the updates to existing plugins I'm using. Win?
- chromakode 11y agoI've been tinkering on one approach to trustworthy OSS ecosystem at https://github.com/chromakode/signet https://github.com/chromakode/signet. The OSS world has grown precipitously in the era of GitHub/npm/etc, and the trust model hasn't caught up. It's not tenable to maintain a GPG keychain for a nested tree of 100 dependencies. Neither is it advisable to keep deferring this problem. We need to come up with a solution for tracking reputation and trustworthy dependencies at this new scale. It's not simply a problem that package repositories like npm can solve for us -- the scope of this problem is human, and an ideal solution will work for both users and developers, and apply to source distributions and multiple package repositories. One of the few silver linings of the events of the last week is that more people are aware of and pondering these issues. I hope we'll see some more discussion and experimentation in this space!
- nickpsecurity 11y agoHere's a reference work with links to key papers on build system security for anyone trying to improve them: http://www.dwheeler.com/essays/scm-security.html http://www.dwheeler.com/essays/scm-security.html Dig into archive.org for Shapiro's OpenCM while you're at it as it had a lot of nice properties. Aegis seemed to as well. Pulling good traits from Wheeler's survey into modern ones would be a good idea. Also, one can re-develop OpenCM, Aegis, etc to have modern features like plugins for common languages/apps or DVCS capabilities. SCM security techniques date back to 80's-early 90's. No excuse for today's solutions to still lack the basics.
- mchahn 11y agoI am always surprised when I hear of developers letting new versions of dependencies go into production. I cannot imagine taking such a chance. Even if every new version of the total app is tested heavily before production, you lose the inherent stability of shipping the same code that is known stable from the users over time. Others have said it is important to use new versions of dependencies to get the bug fixes but I don't see that as a good trade-off.