Compare commits

...
Author SHA1 Message Date
branderson a0e1f50ebd bin/claude-sandbox, bin/claude-sandbox-allow: resolve own location through symlinks
install.sh symlinks both into ~/.local/bin so they can be run by name via
PATH, but BASH_SOURCE[0] resolves to the symlink's own path in that case,
not its target - dirname on it finds ~/.local/bin instead of this repo's
real bin/, and everything derived from it (REPO_ROOT, COMPOSE_FILE,
config/env) resolves against the wrong directory. Hit on first real use:
claude-sandbox tried to open ~/.local/docker/docker-compose.yml. readlink -f
before dirname fixes both scripts.
2026-07-23 18:28:10 -07:00
branderson 95fb8e28a2 Merge pull request 'Security review fixes: hooks overlay, throwaway .claude.json, DNS-rebind, IPv6 fail-loud, docs' (#1) from worktree-security-review-fixes into main
Reviewed-on: branderson/claude-sandbox#1
2026-07-23 18:15:17 -07:00
3 changed files with 19 additions and 2 deletions
+6 -1
View File
@@ -9,7 +9,12 @@
# claude-sandbox ~/repos/myproject
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# readlink -f resolves through the ~/.local/bin/claude-sandbox symlink
# install.sh sets up - without it, BASH_SOURCE[0] is the symlink's own path
# when invoked by name via PATH, so dirname finds ~/.local/bin instead of
# this repo's real bin/, and everything below (REPO_ROOT, COMPOSE_FILE,
# config/env) resolves against the wrong directory entirely.
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
REPO_ROOT="$SCRIPT_DIR/.."
COMPOSE_FILE="$REPO_ROOT/docker/docker-compose.yml"
+3 -1
View File
@@ -92,7 +92,9 @@ done
echo "$domain allowed for the running session ($container)."
if [ "$global" -eq 1 ]; then
env_file="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/config/env"
# readlink -f resolves through the ~/.local/bin symlink install.sh sets
# up - see bin/claude-sandbox's SCRIPT_DIR comment for why this matters.
env_file="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)/config/env"
if [ -f "$env_file" ] && grep -q '^export ALLOWED_DOMAINS=' "$env_file"; then
current=$(sed -nE 's/^export ALLOWED_DOMAINS="(.*)"$/\1/p' "$env_file")
if [[ " $current " == *" $domain "* ]]; then
+10
View File
@@ -195,6 +195,16 @@ setup() {
! grep -qE '^\s*USER\s+node\s*$' <(tail -n 8 "$SANDBOX_DIR/Dockerfile")
}
@test "bin/claude-sandbox and bin/claude-sandbox-allow resolve their own location through symlinks" {
# install.sh symlinks both into ~/.local/bin so they can be run by name
# via PATH. A bare `dirname "${BASH_SOURCE[0]}"` (no readlink -f first)
# resolves against the symlink's own directory in that case, not this
# repo's real bin/ - a real bug hit on first use: claude-sandbox tried
# to open ~/.local/docker/docker-compose.yml instead of this repo's.
grep -q 'dirname "\$(readlink -f "\${BASH_SOURCE\[0\]}")"' "$REPO_ROOT/bin/claude-sandbox"
grep -q 'dirname "\$(readlink -f "\${BASH_SOURCE\[0\]}")"' "$REPO_ROOT/bin/claude-sandbox-allow"
}
@test "bin/claude-sandbox-allow rejects a domain with shell metacharacters" {
run "$REPO_ROOT/bin/claude-sandbox-allow" 'evil.com;touch /tmp/pwned'
[ "$status" -ne 0 ]