←back to thread

1208 points jamesberthoty | 1 comments | | HN request time: 0.203s | source
Show context
aorth ◴[] No.45271988[source]
In the story about the Nx compromise a few weeks ago someone posted a neat script that uses bubblewrap on Linux to run tools like npm more safely by confining their filesystem access. https://news.ycombinator.com/item?id=45034496

I modified the script slightly based on some of the comments in the thread and my own usage patterns:

  #!/usr/bin/env bash
  #
  # See: https://news.ycombinator.com/item?id=45034496
  
  bin=$(basename "$0")
  
  echo "==========================="
  echo "Wrapping $bin in bubblewrap"
  echo "==========================="
  
  exec bwrap \
    --bind ~/.cache ~/.cache \
    --bind "${PWD}" "${PWD}" \
    --dev /dev \
    --die-with-parent \
    --disable-userns \
    --new-session \
    --proc /proc \
    --ro-bind /etc/ca-certificates /etc/ca-certificates \
    --ro-bind /etc/resolv.conf /etc/resolv.conf \
    --ro-bind /etc/ssl /etc/ssl \
    --ro-bind /usr /usr \
    --setenv PATH /usr/bin \
    --symlink /usr/bin /bin \
    --symlink /usr/bin /sbin \
    --symlink /usr/lib /lib \
    --symlink /usr/lib64 /lib64 \
    --tmpfs /tmp \
    --unshare-all \
    --unshare-user \
    --share-net \
    /usr/bin/env "$bin" "$@"
Put this in `~/.local/bin` and symlink it to `~/.local/bin/npm` and `~/.local/bin/yarn` (and make sure `~/.local/bin` is first in your `$PATH`). I've been using it to wrap npm and yarn successfully in a few projects. This will protect you against some attacks that use postinstall scripts to do nefarious things outside the project.
replies(2): >>45272463 #>>45277278 #
whilenot-dev ◴[] No.45272463[source]
> --bind "${PWD}" "${PWD}"

Pardon my ignorance, but couldn't a malicious actor just redefine $PWD before calling a npm script?

replies(1): >>45273273 #
internet_points ◴[] No.45273273[source]
The above script wraps npm. PWD gets evaluated before npm is called (so PWD is expanded in the "outside" environment).

Of course, if your malicious actor has access to your environment already, they can redefine PWD, but that's assuming you're already compromised. This bwrap script is to avoid that malicious actor running malicious install scripts in the first place.

However, I don't think it protects you against stuff like `npm install compromised-executable && node_modules/.bin/execute-compromised-executable` – then you'd have to bwrap that second call as well. Or just bwrap bash to get a limited shell.

replies(1): >>45273634 #
whilenot-dev ◴[] No.45273634[source]
I was more thinking if the malicious script calls npm itself, recursively... it could even redefine $PATH again to skip the next call to the bubblewrap wrapper scriptlet. I don't know if bwrap protects from that.
replies(1): >>45274178 #
1. homebrewer ◴[] No.45274178[source]
You can't really escape it AFAIK, except by using kernel vulnerabilities. Once you're in the sandbox, you can only call and read/write whatever was available when you entered it.

If you have a Linux system nearby, set it up and run `pnpm bash`, and then walk around the system and look at what you can see and do. (Not much.)