5 ms·
>When you run npm install, npm doesn't just download packages. It executes code. Specifically, it runs lifecycle scripts defined in package.json - preinstall, i
by crtasm 1y ago
>When you run npm install, npm doesn't just download packages. It executes code. Specifically, it runs lifecycle scripts defined in package.json - preinstall, install, and postinstall hooks.
What's the legitimate use case for a package install being allowed to run arbitrary commands on your computer?
Quote is from the researchers report https://www.koi.ai/blog/phantomraven-npm-malware-hidden-in-invisible-dependencies https://www.koi.ai/blog/phantomraven-npm-malware-hidden-in-i...
edit: I was thinking of this other case that spawned terminals, but the question stands: https://socket.dev/blog/10-npm-typosquatted-packages-deploy-credential-harvester https://socket.dev/blog/10-npm-typosquatted-packages-deploy-...
- j1elo 1y agoEasy example that I know of: the Mediasoup project is a library written in C++ for streaming video over the internet. It is published as a Node package and offers a JS API. Upon installing, it would just download the appropriate C++ sources and compile them on the spot. The project maintainers wanted to write code, not manage precompiled builds, so that was the most logical way of installing it. Note that a while ago they ended up adding downloadable builds for the most common platforms, but for anything else the expectation still was (and is, I guess) to build sources at install time.
- exe34 1y agohow hard would it be to say "upon first install, run do_sketchy_shit.sh to install requirements"?
- lelandbatey 1y agoPeople want package managers to do that for them. As much as I think it's often a mistake (if your stuff requires more than expanding archives different folders to install, then somewhere in the stack something has gone quite wrong), I will concede that because we live in an imperfect world, other folks will want the possibility to "just run the thing automatically to get it done." I hope we can get to a world where such hooks are no longer required one day.
- exe34 1y agoyes that's why npm is for them. I'd rather download the libraries that I need one by one.
- SoftTalker 1y agoBut most users would do that without inspecting it at all, and a fair number would prefix it with “sudo” out of habit.
- cindyllm 1y ago[dead]
- nkrisc 1y agoBut that’s at least a conscious and explicit action the user chooses to make and is explicitly aware of making.
- hombre_fatal 1y agoThat's fine, and it's still better than doing it on install.
- exe34 1y agoyou can always add --am-an-idiot as a switch to npm install.
- cyphar 1y agorpm and dpkg both provide mechanisms to run scripts on user machines (usually used to configure users and groups on the user machine), so this aspect is not an NPM-specific. Rust has the same thing with build.rs (which is necessary to find shared C libraries for crates that link with them) so there is a legitimate need for this that would be hard to eliminate. Personally, I think the issue is that it is too easy to create packages that people can then pull too easily. rpm and dpkg are annoying to write for most people and require some kind of (at least cursory) review before they can be installed on user's systems from the default repos. Both of these act as barriers against the kinds of lazy attacks we've seen in the past few months. Of course, no language package registry has the bandwidth to do that work, so Wild West it is!
- scheme271 1y agorpm and dpkg generally install packages from established repos that vet maintainers. It's not much but having to get one or two other established package authors to vouch for you and having to have some community involvement before you can publish to distro repos is something.
- cyphar 1y agoI agree, that is what I talk about in the second paragraph! ;)
- ares623 1y agoYou see, when you treat everything as a "product", this is what you end up with.
- IgorPartola 1y agoHard. In npm land you install React and 900 other dependencies come with it. And how ok are you reviewing every single one of those scripts and manually running them? Not that it is good that this happens but realistically most people would just say “run all” and let it run instead of running each lifecycle script by hand.
- jacquesm 1y agoMy solution is to bypass React entirely. I'd much rather have a smaller, possibly less functional or pretty front end than to have to worry about this stuff continuously. I would not get any work done. There is no way I'm going to take on board 900 dependencies which I will then inflict on the visitors to my website.
- exe34 1y agothe only way I'd use react in a project is to download the react.js build. I don't see why people want to download 900 dependencies.
- IgorPartola 1y agoI am people and I don’t want to download 900 dependencies. But if I want to use React or Vue or anything but the most trivial JS libraries or frameworks I am held hostage by the fact that their dependencies have dependencies. Surely there are ways to just stick to absolute basics and you can get quite far with what is built in or some very small libraries, but I guess it depends on where you would be most productive.
- lenkite 1y agoBelieve such build tools and processes should be run inside a container environment. Maybe once all OS have native, cheap and lean containers and permit dead simple container execution of scripts, this will be possible.
- codedokode 1y agoGoogle's OS, Android, has sandboxes. It's some Linux problem that they do not want to backport it.
- immibis 1y agoIt just has Linux user IDs. They're in every Linux.
- codedokode 1y agoI think that was long time ago, because this doesn't allow to request permissions in runtime.
- immibis 1y agoPermissions are not granted through Linux itself. Permissions are something checked by separate processes when you connect with those processes.
- philipwhiuk 1y agoRunning a C compiler on everyone's machines to avoid a bit of work is extremely dumb.
- cleartext412 1y agoModern internet is build on premise of repeatedly running megabytes of javascript on everyone's machines to avoid a bit of work.
- squidsoup 1y agopnpm v10 disables all lifecycle scripts by default and requires the user to whitelist packages. https://github.com/orgs/pnpm/discussions/8945 https://github.com/orgs/pnpm/discussions/8945
- chrisweekly 1y agoOne of the many reasons there is no good reason to use npm; pnpm is better in every way.
- sroussey 1y agoIt’s just security theater in the end. You can just as easily put all that stuff in the package files since a package is installed to run code. You have that code then do all the sketchy stuff. What’s needed is an entitlements system so a package you install doesn’t do runtime stuff like install crypto mining software. Even then…
- theodorejb 1y agoI would expect to be able to download a package and then inspect the code before I decide to import/run any of the package files. But npm by default will run arbitrary code in the package before developers have a chance to inspect it, which can be very surprising and dangerous.
- sroussey 1y agonpm used to do that. bun never did. No idea about the past for pnpm or yarn.
- Mogzol 1y agoA package, especially a javascript package, is not necessarily installed to run code, at least not on the machine installing the package. Many packages will only be run in the browser, which is already a fairly safe environment compared to running directly on the machine like lifecycle scripts would. So preventing lifecycle scripts certainly limits the number of packages that could be exploited to get access to the installing machine. It's common for javascript apps to have hundreds of dependencies, but only a handful of them will ever actually run as code on the machine that installed them.
- vorticalbox 1y agoOne use case is downloading of binaries. For example mongo-memory-server [0] will download the mongoDB binary after you have installed it. [0] https://www.npmjs.com/package/mongodb-memory-server https://www.npmjs.com/package/mongodb-memory-server
- 8note 1y agowhy would i want that though, compared to downloading that binary in the install download? the npm version is decoupled from the binary version, when i want them locked together
- jonhohle 1y agoI think it falls into a few buckets: A) maintainers don’t know any better and connect things with string and gum until it most works and ship it B) people who are smart, but naive and think it will be different this time C) package manager creators who think they’re creating something that hasn’t been done before, don’t look at prior art or failures, and fall into all of the same holes literally every other package manager has fallen into and will continue to fall into because no one in this industry learns anything.
- madeofpalk 1y agoAnd now optional dependencies negate the need for this. Your package manager can just download platform-specific binaries automatically https://docs.npmjs.com/cli/v7/configuring-npm/package-json#optionaldependencies https://docs.npmjs.com/cli/v7/configuring-npm/package-json#o...
- DangitBobby 1y agoI seem to recall Husky at one point using lifecycle hooks to install the git hooks configured in your repository when running NPM install.
- mock-possum 1y agoPlaywright does it too. Or at least, I’ve worked a place that used npm install hooks to setup husky and install playwright browser binaries
- interstice 1y agoNotable times this has bitten me include compiling image compression tools for gulp and older versions of sass, oh and a memorable one with openssl. Downloading a npm package should ideally not also require messing around with c compilation tools.
- deleted 1y ago[deleted]
- zahlman 1y ago> doesn't just download packages. It executes code. Specifically, it It pains me to remember that the reason LLMs write like this is because many humans did in the training data.
- jsrozner 1y agoThat whole koi blog post is sloppy AI garbage, even if it's accurate. So obnoxious.
- marcus_holmes 1y agoIs the objection the small sentence that could have been a clause?
- zahlman 1y agoThe objection is to the redundant, flowery prose overall, and the overall inaccuracy. (Of course the installer "doesn't just download packages"; installation at minimum would also involve unpacking the archive and putting the files in the right place....) In about as much text, we could explain far better why and how NPM's behaviour is risky: > When you install a package using `npm install`, NPM may also run arbitrary code from the package, from multiple hook scripts specified in `package.json`, before you can even audit the code.
- ChrisMarshallNY 1y agoSwift Package Manager[0] executes a Swift script. The Package.swift file[1] (the manifest) is actually an executed source file. I assume that it's heavily sandboxed, though, so it may be difficult to leverage. [0] https://docs.swift.org/swiftpm/documentation/packagemanagerdocs/ https://docs.swift.org/swiftpm/documentation/packagemanagerd... [1] https://developer.apple.com/documentation/packagedescription https://developer.apple.com/documentation/packagedescription
- bandrami 1y agoOK but have you seen how many projects' official installation instructions are some form of curl | bash?
- codedokode 1y agoIn most cases to use a library you just need to download files and place them into a directory.
- dns_snek 1y agoBoth post-install scripts and curl|bash scripts are just scapegoats of supply chain security with similar faulty reasoning.
- Timshel 1y agoThere is the "--ignore-scripts" option and had no issue using it for now.
- maxloh 1y agoMany front end tools are written in a faster language. For example, the next version of TypeScript compiler, SASS, SWC (minifier), esbuild (bundler used by Vite), Biome (formatter and linter), Oxc (linter, formatter and minifier), Turbopack (bundler), dprint (formatter), etc. They use proinstall script to fetch pre-built binaries, or compile from source if your environment isn't directly supported.
- styanax 1y ago> What's the legitimate use case for a package install being allowed to run arbitrary commands on your computer? The paradigm itself has been in package managers since DEB and RPM were invented (maybe even Solaris packages before that? it's been a minute since I've Sun'd); it's not the same as NPM, a more direct comparison is the Arch Linux AUR - and the AUR has been attacked to try and inject malware all year (2025) just like NPM. As of the 26th (5 days ago) uploads are disabled as they get DDOSed again. https://status.archlinux.org/ https://status.archlinux.org/ (spirit: it's the design being attacked, pain shared between AUR and NPM as completely disparate projects). More directly to an example: the Linux kernel package. Every Linux distribution I'm aware of runs a kernel package post-install script which runs arbitrary (sic) commands on your system. This is, of course, to rebuild any DKMS modules, build a new initrd / initramfs, update GRUB bootloader entries, etc. These actions are unique outputs to the destination system and can't be packaged. I have no data in front of me, but I'd speculate 70% (?) of DEB/RPM/PKG packages include pre / post install/uninstall scriptlets, it's very common in the space and you see it everywhere in use.
- matheusmoreira 1y agoThere's nothing inherently wrong with that. The problem is npm allows any random person to upload packages. It's completely untrusted. Contrast that with Linux distributions which have actual maintainers who take responsibility for their packages. They don't generally allow malware to make it into the official software repositories. In many cases they went as far as meeting each other in person just to set up a decentralized root of trust with PGP. It's so much better and more trustworthy. The truth is npm, pip, rubygems, cargo and all the other programming language package managers are just fancier versions of the silly installation instructions you often find in README files that tell people to curl some script and pipe it into bash.
- graemep 1y agoEven when random people are allowed to contribute (AUR, PPAs) there seems to be more scrutiny and fewer incidents. Possibly because they are secondary to the main repos and possibly because the people who use them are made aware of the risks. NPM etc. are a bit like Arch would be if everything was in AUR.
- cozzyd 1y agoWith PPAs or COPR (or third party repositories, e.g. slack) you have to explicitly enable each repository too. Even if a repository is enabled by package you are prompted the first time a new repository is used (actually I don't know if that's true when gpgcheck is disabled? If not this would be an easy fix in apt/dnf)