alias npm='docker run --rm -it -v ${PWD}:${PWD} --net=host --workdir=${PWD} node:25-bookworm-slim npm'
- No access to my env vars
- No access to anything outside my current directory (usually a JS project).
- No access to my .bashrc or other files.
Ref: https://ashishb.net/programming/run-tools-inside-docker/Also I can recommend pnpm, it has stopped executing lifecycle scripts by default so you can whitelist which ones to run.
If you want to protect your machine from malicious dependencies you must run everything in a sandbox all the time, not just during the installation phase. If you follow that advice then disabling post-install scripts is pointless.
The supply chain world is getting more dangerous by the minute and it feels like I'm watching a train derail in slow motion with more and more people buying into the idea that they're safe if they just disable post-install scripts. It's all going to blow up in our collective faces sooner or later.
If I had malicious intentions, I would probably typo squat popular plugins/lsps that will execute code automatically when their editor runs. A compromised neovim or vscode gives you plenty of user permissions, a full scripting language, ability to do http calls, system calls, etc. Most LSPs are installed globally, doesn't matter if you downloaded it via a docker command.
I use sandbox-run: https://github.com/sandbox-utils/sandbox-run
The above simple alias may work for node/npm, but it doesn't generalize to many other programs available on the local system, with resources that would need to be mounted into the container ...
If only :(
alias npm='docker run --rm -it -v "$PWD:$PWD" --net=host --workdir="$PWD" node:25-bookworm-slim npm'
...Does this always work? I don't use much JS. Doesn't NPM sometimes build against system libs, which could be different in the container?Coming from "make" with repeatable and predictable builds, I was appalled that you run this thing and you have no idea what it will download and what it will produce. Could be something different the next time you run it! Who knows!
I also found it bizarre that even for things that just generate CSS, you are expected to integrate it into your npm thing. I mean, generating CSS from a configuration is a function. It's a make recipe. Why does it need to be an npm library dependency with all the associated mess? I managed to work around it for a number of packages by freezing entire npm setups inside docker containers, which gave me reproducible builds — but it's a losing battle.
Did you then spend a month or two inspecting that setup? Did you do that after every dependency upgrade?
Also both NPM and PNPM already freeze dependencies for you by default without any arcane docker setups.
I don't think the old C/C++ way of relying on distro package managers would allow for the fast ecosystems people work nowadays.
Things are changing though, and people are pushing for more secure package managers with the same feature set as the old ones, which is possible.
I think this is the missing piece on the first wondering part of your comment. But I don't think we should be bashing the means without understanding the reasons
How does that work when enevitably those npm packages are shown to have vulnerabilites?
Too lazy to write, too cheap to pay for it, that's half of open source.
Now what's going to dominate stackoverflow answers, thoughtful articles on how to program? Or gratis npm/uv installable libraries that hide the actual solution details in between tests and polyfills and readmes, that end up just download another dependency while contributing enough lines of code so that the author can safely put it in their resume and grift over the oss ecosystem to get a cushy 300k/yr job at an extended faang where they are in charge of an ad pixel tracker or yet another one of those wallet things that are just an IO proxy for money but they get to keep some comission if they spend enough money on ads to convince someone to use the thing once and then it becomes their main neo(not) bank* forever.
*for regulatory reasons we must not call it a bank, but it's a bank
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-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-...
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/ (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.
To me the entire JavaScript ecosystem is broken. And a typo in your “npm -i” is sufficient to open up yourself for a supply-chain attack. Could the same happen with NuGet or Maven? Sure!
But at least in these languages and environments I have a huge Standard Library and very few dependencies to take. It makes me feel much more in control.
When I build backend in flask or Django, I specifically type the python packages that I need. But front end development seems like a Pandora box of vulnerabilities
When I iterate with new versions of a package that I’ve never promoted anywhere, each version gets hundreds of downloads in the first day or two of being published.
86,000 people did not get pwnd, possibly even zero.
Somewhat related, I also have a small homelab running local services and every now and then I try a new technology. occasionally I’ll build a little thing that is neat and could be useful to someone else, but then I worry that I’m just a target for some bot to infiltrate because I’m not sophisticated enough to stop it.
Where do I start?
I found it very interesting that they used common AI hallucinated package names.
I have used Node, I would not go near the NPM auto install Spyware service.
How is it possible that people keep this service going, when it has been compromised so regularly?
How's it possible that people keep using it?
There is nothing about Go, or Cargo, or Nuget, or any of the other systems that prevents criminals from committing crimes. Some cleverness can slow them down, or block certain roads to exploiting these systems, but managing risk in a supply chain is essential no matter which technology ecosystem is used.
Let's stop name-calling and throwing shade at specific tools and communities and get better at educating new-comers to the trade, and shaming and ostracizing the cyber-criminals who are causing the problems.
I think security controls on macOS have been trending in the right direction to tackle these types of things comprehensively with secure domains, sandboxing, etc. but there is always a war of how much friction is too much when it comes to security.
We saw the same thing with 2SV where people were vehemently against it, and now many are clamoring that it should be the only way to be able to do things like publish packages (I agree! I have no issue jumping through some extra hoops when I publish something a million people will install).
This might be a hot take but I think a lot of loud mouths with their personal preferences have been holding security in this space back for a while, and recently people seem to be getting tired of it and pushing through. The engineering leadership that won't just make these types of high impact security decisions because it might irritate a handful of highly opinionated workflows is unfortunate!
I don't usually get to say 'I told you so' within 24 hours of a warning, but JS is special like that.