5 ms·
If you're interested in preventing this sort of thing, I'd appreciate comments on this [RFC](https://github.com/npm/rfcs/pull/488 https://github.com/npm/rfcs/pu
by tolmasky 5y ago
If you're interested in preventing this sort of thing, I'd appreciate comments on this [RFC](https://github.com/npm/rfcs/pull/488 https://github.com/npm/rfcs/pull/488) I just submitted to npm to make install scripts opt-in instead of default behavior. While of course not perfect, this simple change would certainly go a long way in increasing the difficulty in creating these sorts of attacks, as right now as long as a computer even installs the packages in question, not even running any code in the package, the malicious program has a chance at running.
RFC: https://github.com/npm/rfcs/pull/488 https://github.com/npm/rfcs/pull/488
Related HN post: https://news.ycombinator.com/item?id=29122473 https://news.ycombinator.com/item?id=29122473
- chakkepolja 5y agoProblem is, as someone mentioned in the GitHub thread as well, people just press OK, especially if it's a transitive dependency.
- Me1000 5y agoI don't think anyone is claiming making install script opt-in will fix all the problems. But adding any friction discourages the behavior. And if the norm changes, it's reasonable to believe package maintainers will start opting for dependencies that don't require install scripts. Thus further encouraging people to not include them with their packages.
- tolmasky 5y agoI've answered this on GitHub, but will provide an answer here too. Packages aren't like end-user software, for two important reasons: 1. The people involved are developers using development components, who are much better equipped to understand an installation failure and take proper action than an end user who is just trying to click through to play a video game or something. But more importantly: 2. The vast majority of the installs happen on automated machines (like CI), where you definitely want to fail when something drastically different happens like a new package is all of a sudden running a script. The tests would fail, you would look at the reason, it would be because some weird script is about to run on the machine, and you'd adjust your PR accordingly. This allows multiple levels of consideration: 1) the original author deciding to do something about the failed install (even if it's just appending the flag and not thinking about it), and 2) the PR reviewer having code-as-data evidence that this code change would mean new foreign code not represented in the commits will be running on their machines. This is huge. The other important point about this is that packages precisely have different risk models depending on whether you are installing things locally or on production machines, where a malicious package could be catastrophic. That's why the RFC allows you to have individual user configuration where you explicitly allow certain packages "from now on" (which is I think the way most people want to think about this: the first time you install something and it warns you and you look into it, but from then on you say "this one is good"). On the other hand, the actual scripts and repository have no such configuration and thus require the installation to include the specific flags, again, clearly documenting the expected results of a seemingly innocent process that can actually currently have bad consequences.
- Me1000 5y agoYour comments on the RFC cover this, but I want to highlight a two things: 1) The vast majority of packages on npm don't require install scripts to work. 2) Many of them that currently include install scripts are just ads asking people to contribute code or money to their project.
- forty 5y agoIsn't that only useful for the very rare minority of people that install packages then don't run the code right after? :)
- Me1000 5y agoMany packages on npm are not run in a local node environment, they run in a browser which is sandboxed. Regardless, just because there are additional vectors to exploit the user doesn't mean closing off one vector isn't worth doing.
- forty 5y agoYeah I also thought of that but aren't front end devs running some kind of unit test in node? Do they always run everything in their browser? (Honest question, I'm a BE person)
- schemescape 5y agoI initially had the same thought, but I came to a different conclusion because the presence of an install script is not a given for most packages. For example, if I installed a command line arguments parser and it claimed to require running a setup script, I would immediately be very suspicious. For a huge package like TypeScript, I'd probably just immediately let the script run and trust Microsoft to not publish malware (and NPM to not change the package contents).
- tolmasky 5y agoThe fact that they don't need to be run is what makes them so hard to spot and easy to sneak in. This allows for some very hard to mitigate strategies. It's easier to sneak in packages into metadata files like package.jsons than create "excuses" to import files that aren't really needed. It can be abused in more complicated ways as well, like for example: 1. You add a totally "safe" dependency that you control, let's call it "shell-dependency", as an innocuous part of a PR to a "popular-package". Again, even if you inspect this package, it's totally fine. The current version of shell-dependency is 1.0.0, but it of course goes into the package.json as "1.x.x" 2. You now add malicious dependency to shell-dependency, and bump shell-dependency to 1.0.1, meaning every consumer of "popular-package" now gets your "malicious-package". Notice that this was accomplished with zero traceable GitHub history. Unless every package up the line uses a package-lock.json (which is explicitly recommended against unless you are an end-user application), "malicious-package" is able to enter the dependency chain undetected. If it required some sort of code import, then it would have more opportunities to be spotted. There are of course ways to do this with attacks that require running code as well, but this makes it super easy, especially considering that people often install packages as root, even when they run their apps not as root.
- ricardobayes 5y agoNon-tech solution is to pin versions and read (hacker)news before updating.