6 ms·
Here's my `npm` command these days. It reduces the attack surface drastically. alias npm='docker run --rm -it -v ${PWD}:${PWD} --net=host --workdir=${PWD} no
by ashishb 1y ago
Here's my `npm` command these days.
It reduces the attack surface drastically.
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/ https://ashishb.net/programming/run-tools-inside-docker/
- sthuck 1y agoThat definitely helps and worth doing. On Mac though I guess you need to move the entire development to containers due to native dependencies.
- chuckadams 1y agoMy primary dev environment is containers, but you can do a hell of a lot with nix on a mac.
- genpfault 1y ago> triple-backtick code blocks If only :(
- phiresky 1y agoThat seems a bit excessive to sandbox a command that really just downloads arbitrary code you are going to execute immediately afterwards anyways? Also I can recommend pnpm, it has stopped executing lifecycle scripts by default so you can whitelist which ones to run.
- simpaticoder 1y agopnpm has lots of other good attributes: it is much faster, and also keeps a central store of your dependencies, reducing disk usage and download time, similar to what java/mvn does.
- ashishb 1y ago> That seems a bit excessive to sandbox a command that really just downloads arbitrary code you are going to execute immediately afterwards anyways? I won't execute that code directly on my machine. I will always execute it inside the Docker container. Why do you want to run commands like `vite` or `eslint` directly on your machine? Why do they need access to anything outside the current directory?
- bandrami 1y agoI get this but then in practice the only actually valuable stuff on my computer is... the code and data in my dev containers. Everything else I can download off the Internet for free at any time.
- ashishb 1y agoNo. Most valuable data on your system for a malware author is login cookies and saved auth tokens of various services.
- hinkley 1y agoMaybe keylogging for online services. But it is true that work and personal machines have different threat vectors.
- spicybright 1y agoYes, but I'm willing to bet most workers don't follow strict digital life hygiene and cross contaminate all the time.
- kolme 1y agoYou don't have any stored passwords? Any private keys in your `.ssh/`? DB credentials in some config files? And the list goes on and on.
- bandrami 1y ago
- ashishb 1y ago> Also I can recommend pnpm, it has stopped executing lifecycle scripts by default so you can whitelist which ones to run. Imagine you are in a 50-person team that maintains 10 JavaScript projects, which one is easier? - Switch all projects to `pnpm`? That means switching CI, and deployment processes as well - Change the way *you* run `npm` on your machine and let your colleagues know to do the same I find the second to be a lot easier.
- afavour 1y agoThere are a great many extra perks to switching to pnpm though. We switched on our projects a while back and haven’t looked back.
- fragmede 1y agoAm I missing something? Don't you also need to change how CI and deployment processes call npm? If my CI server and then also my deployment scripts are calling npm the old insecure way, and running infected install scripts/whatever, haven't I just still fucked myself, just on my CI server and whatever deployment system(s) are involved? That seems bad.
- ashishb 1y agoYour machine has more projects, data, and credentials than your CI machine, as you normally don't log into Gmail on your CI. So, just protecting your machine is great. Further, you are welcome to use this alias on your CI as well to enhance the protection.
- arghwhat 1y agoAttacking your CI machines means to poison your artifacts you ship and systems they get deployed to, get access to all source it builds and can access (often more than you have locally) and all infrastructure it can reach. CI machines are very much high-value targets of interest.
- fragmede 1y ago> Further, you are welcome to use this alias on your CI as well to enhance the protection. Yes, but if I've got to configure that across the CI fleet as well as in my deploy system(s) in order to not get, and also be distributing malware, what's the difference between having to do that vs switching to pnpm in all the same places? Or more explicitly, your first point is invalid. Whether you ultimately choose to use docker to run npm or switch to pnpm, it doesn't count to half-ass the fix and only tell your one friend on the team to switch, you have to get all developers to switch AND fix your CI system, AND also your deployment system (s) (if they are exposed). This comment proffers no option on which of the two solutions should be preferred, just that the fix needs to made everywhere.
- Kholin 1y agoI've tried use pnpm to replace npm in my project, it really speed up when install dependencies on host machine, but much slower in the CI containers, even after config the cache volume. Which makes me come back to npm.
- deleted 1y ago[deleted]
- worthless-trash 1y ago> That seems a bit excessive to sandbox a command that > really just downloads arbitrary code you are going to > execute immediately afterwards anyways? I don't want to stereotype, but this logic is exactly why javascript supply chain is in the mess its in.
- tetha 1y agoAt work, we're currently looking into firejail and bubblewrap a lot though and within the ops-team, we're looking at ways to run as much as possible, if not everything through these tools tbh. Because the counter-question could be: Why would anything but ssh or ansible need access to my ssh keys? Why would anything but firefox need access to the local firefox profiles? All of those can be mapped out with mount namespaces from the execution environment of most applications. And sure, this is a blacklist approach, and a whitelist approach would be even stronger, but the blacklist approach to secure at least the keys to the kingdom is quicker to get off the ground.
- ashishb 1y agofirejail, bubblewrap, direct chroot, sandbox-run ... all have been mentioned in this thread. There is a gazillion list of tools that can give someone analysis paralysis. Here's my simple suggestion: all of your backend team already knows (or should) learn Docker for production deployments. So, why not rely on the same? It might not be the most efficient, but then dev machines are mostly underutilized anyway.
- johannes1234321 1y ago> command that really just downloads arbitrary code you are going to execute immediately afterwards anyways? By default it directly runs code as part of the download. By isolation there is at least a chance to do some form of review/inspection
- bitbasher 1y agoThere are so many vectors for this attack to piggyback off from. 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.
- ashishb 1y ago> 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. Running `npm` inside Docker does not solve this problem. However, running `npm` inside Docker does not make this problem worse either. That's why I said running `npm` inside Docker reduces the attack surface of the malicious NPM packages.
- dns_snek 1y agoI think this approach is harmful because it gives people a false sense of security and makes them complacent by making them feel like they're "doing something about it even if it's not perfect". It's like putting on 5 different sets of locks and bolts on your front door while leaving the back door unlocked and wide open during the night.
- hacb 1y agoDone is better than perfect, and a 100% secure system doesn't exist. Given how prolific those supply-chain attacks are, any mitigation (even if imperfect) seems to be good step toward protecting yourself and your assets
- dns_snek 1y agoThis isn't just "imperfect", it's so deeply flawed that the next minor "mutation" of supply chain attack tactics is guaranteed to wipe you out if you rely on it. It's just a matter of time, it could be tomorrow, next month, maybe a year from now. Setting up a fully containerized development environment doesn't take a lot of effort and will provide the benefits you think you're getting here - that would be the "imperfect but good enough for the moment" kind of solution, this is just security theater. Every time I make this point someone wants to have the "imperfect but better than nothing" conversation and I think that shows just how dangerous the situation is becoming. You can only say that in good conscience if you follow it up with "better than nothing ... until I figure out how to containerize my environment over the weekend"
- kernc 1y ago> alias npm=... I use sandbox-run: https://github.com/sandbox-utils/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 ...
- ashishb 1y ago> The above simple alias may work for node/npm, but it doesn't generalize for many other programs that are available on the local system, with resources that would somehow have to get mounted into the container ... Thanks. You are right, running inside Docker won't always work for local commands. But I am not even using local commands. Infact, I have removed `yarn`, `npm`, and several similar tools already from my machine. It is best to run them inside Docker. > I use sandbox-run: https://github.com/sandbox-utils/sandbox-run https://github.com/sandbox-utils/sandbox-run How does this work if my local command is a Mac OS binary? How will it run inside Docker container?
- fingerlocks 1y agoOr use ‘chroot’. Or run it as a restricted owner with ‘chown’. Your grandparents solutions to these problems still work.
- roryirvine 1y agoThat'll still allow access to env vars, and interact with other processes owned by the same user. At the very least, you really need to add process isolation / namespacing as well - at which point it's going to be easier to just use the sandboxing / containerisation tool of your choice to manage it all for you.
- lelanthran 1y agoWon't that still download malicious packages that are dep?
- ashishb 1y agoYeah but those deps won't access your browser cookies and tour secret keys that are outside the current directory.
- silverwind 1y agoThis will break native dependencies when the host platform is not the same as the container platform.
- ashishb 1y agoMy host is Mac OS. My container platform is Linux. Can you share an example where this approach will cause a failure?
- dns_snek 1y agoThis folk-wisdom scapegoating of post-install scripts needs to stop or people are going to get really hurt by the false sense of security it's creating. I can see the reasoning behind this, I really do, it sounds convincing but it's only half the story. 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.
- lioeters 1y agoYou're right, it's not just about post-install scripts nor NPM and JavaScript. This is a deep fundamental issue in software development practices across most programming language ecosystems. And not only open-source, since proprietary code is often even worse about vetting dependencies. More eyes are better, therefore open source (or source available) is a prerequisite for security. Improving NPM's processes, having more companies auditing packages, changing the way NPM the tool works - that's all good but far from enough, it doesn't actually address the root vulnerability, which is that we're way too comfortable running other people's arbitrary code. Containerization and strict permissions system by default seem to be where we're headed.
- ashishb 1y agoExactly for JS code, run all inside the container, all the time. I have been doing it for weeks now with no issues.
- a022311 1y agoNot sure how secure this really is, because it's fairly easy to break out of a Docker container with the default settings (due to the fact that the kernel is shared between containers and the host, unlike with VMs). Rootless Docker (or better, Podman) would improve security greatly.
- ashishb 1y agoCan you show an example of how can a malicious package break out of docker?
- a022311 11mo agoThere have been quite a few exploits over the years, with the most recent public CVE 2 years ago [1]. Your specific setup uses `--net=host` and this opens you up to potential vulnerabilities (see [2]). You also shouldn't forget that containers have unrestricted network access bu default anyway. Even if your device is safe, they may be able to infect other vulnerable devices on your network. [1]: https://docs.docker.com/security/security-announcements/#docker-security-advisory-multiple-vulnerabilities-in-runc-buildkit-and-moby https://docs.docker.com/security/security-announcements/#doc... [2]: https://github.com/0xn3va/cheat-sheets/blob/main/Container/Escaping/host-networking-driver.md https://github.com/0xn3va/cheat-sheets/blob/main/Container/E...
- TacticalCoder 1y ago[dead]
- redat00 1y agoDoesn't Docker run as `root` by default, and alter the permission of your folder by taking ownership and making it as `root:root` ?
- redat00 1y agoJust tested it and apparently it's not the case, neat!
- Intralexical 1y agoYou should probably put some quotes around `$PWD`: 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?
- ashishb 11mo ago> You should probably put some quotes around `$PWD`: Yeah, fair point. > Doesn't NPM sometimes build against system libs, which could be different in the container? Yes, and I run all JS inside a container.