aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/dot_local/bin/executable__sandbox-net-parser
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:12 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:12 +0100
commit1a8a19e6286aa58c5a46f03882f8f09e54456051 (patch)
tree6d82622e37268ce466104f81cb3b53a20f0ad9b3 /dot_local/bin/executable__sandbox-net-parser
parent8ebe3f106e53dc4032428a2e3435c4feea969087 (diff)
downloaddotfiles-1a8a19e6286aa58c5a46f03882f8f09e54456051.tar.gz
dotfiles-1a8a19e6286aa58c5a46f03882f8f09e54456051.tar.bz2
dotfiles-1a8a19e6286aa58c5a46f03882f8f09e54456051.zip
feat(sandbox): bwrap wrappers for mpv, yt-dlp, streamlink
These three tools are the native (non-flatpak) network parsers in the install set — every other internet-facing app is already flatpak'd. The threat model is a RCE in a subtitle/extractor/muxer that walks $HOME looking for SSH keys, GPG keyring, pass store, cloud tokens, etc. Approach (defence in depth, not full sandboxing): - bwrap --bind / / keeps Wayland, PipeWire, DBus, GPU, hwaccel and all config files working transparently. - --tmpfs over known-sensitive dirs (.ssh, .gnupg, .password-store, .config/gh, .config/op, .aws, .local/share/keyrings) blanks them from the sandbox view; a compromised parser literally cannot see them. - inner PATH stripped of ~/.local/bin so streamlink's spawn of `mpv` resolves to /usr/bin/mpv and does not re-enter the sandbox. - --die-with-parent + --new-session for tidy lifecycle. - Escape hatch: SANDBOX=0 mpv ... bypasses for one invocation. - Graceful degradation if bwrap is missing (warns and execs anyway). bubblewrap added explicitly to meta/base.txt (was implicit via flatpak). Wrappers in ~/.local/bin shadow /usr/bin via dot_zprofile:15 PATH order. Not symlinked into the Ubuntu VM (nix/vm.nix does not touch ~/.local/bin), which is fine: those tools on the headless VM don't need sandboxing.
Diffstat (limited to 'dot_local/bin/executable__sandbox-net-parser')
-rw-r--r--dot_local/bin/executable__sandbox-net-parser58
1 files changed, 58 insertions, 0 deletions
diff --git a/dot_local/bin/executable__sandbox-net-parser b/dot_local/bin/executable__sandbox-net-parser
new file mode 100644
index 0000000..648ad0f
--- /dev/null
+++ b/dot_local/bin/executable__sandbox-net-parser
@@ -0,0 +1,58 @@
+#!/usr/bin/env sh
+# Sandbox wrapper for tools that parse data from untrusted network
+# sources (mpv, yt-dlp, streamlink). The threat model is RCE in a
+# subtitle / muxer / extractor that walks the user's home directory
+# looking for SSH/GPG keys, password store, cloud tokens, etc.
+#
+# Compromise: most of the system is still reachable (--bind / /), so
+# Wayland, PipeWire, DBus, GPU, hardware accel and config files all
+# work transparently; the sandbox only tmpfs-shadows known-sensitive
+# directories so a compromised parser cannot read them.
+#
+# Set SANDBOX=0 to bypass entirely for a single invocation:
+# SANDBOX=0 mpv weird-codec-file.mkv
+#
+# Usage (called by the per-tool wrappers): _sandbox-net-parser /usr/bin/mpv "$@"
+
+set -eu
+
+if [ "${SANDBOX:-1}" = "0" ]; then
+ bin=$1
+ shift
+ exec "$bin" "$@"
+fi
+
+if ! command -v bwrap >/dev/null 2>&1; then
+ printf '%s: bwrap not installed; falling back to direct exec\n' "$0" >&2
+ bin=$1
+ shift
+ exec "$bin" "$@"
+fi
+
+bin=$1
+shift
+
+# Prevent re-entry: any tool spawned inside the sandbox that resolves
+# `mpv`/`yt-dlp`/`streamlink` via PATH (e.g. streamlink launching mpv)
+# must find the real binary, not another wrapper that would try to
+# nest a second bwrap and fail. Strip ~/.local/bin and nix-profile/bin
+# from PATH inside the namespace.
+inner_path='/usr/local/sbin:/usr/local/bin:/usr/bin'
+
+exec bwrap \
+ --bind / / \
+ --dev-bind /dev /dev \
+ --proc /proc \
+ --tmpfs /root \
+ --tmpfs "$HOME/.ssh" \
+ --tmpfs "$HOME/.gnupg" \
+ --tmpfs "$HOME/.password-store" \
+ --tmpfs "$HOME/.config/gh" \
+ --tmpfs "$HOME/.config/op" \
+ --tmpfs "$HOME/.aws" \
+ --tmpfs "$HOME/.local/share/keyrings" \
+ --tmpfs "$HOME/.local/share/pass" \
+ --setenv PATH "$inner_path" \
+ --die-with-parent \
+ --new-session \
+ -- "$bin" "$@"