Description
openshell sandbox download exits 0 when the download request is rejected because the source path is outside the sandbox workspace (/sandbox). The path-traversal guard correctly blocks the request and prints a user-facing error, but the failure is not propagated to the process exit code — scripts, test frameworks, and downstream tooling cannot detect the rejection.
Downstream report with full QA reproduction: NVIDIA/NemoClaw#7367. NemoClaw has added caller-side defenses (NVIDIA/NemoClaw#7371, NVIDIA/NemoClaw#7416 — probe the source and verify an artifact was written), but those cannot fix the CLI's own exit code, which is what that issue's repro exercises.
Reproduction Steps
- Have a sandbox onboarded and running (single active gateway).
- Run:
openshell sandbox download {sandbox-name} /etc/passwd /tmp/p
- Check the exit code:
echo $?
- Repeat with
/sandbox/../etc/passwd and /var/lib/openshell/supervisor/creds.json — same behavior.
Observed:
$ openshell sandbox download {sandbox-name} /etc/passwd /tmp/p; echo $?
Downloading sandbox:/etc/passwd -> /tmp/p
Error: x sandbox source path '/etc/passwd' is outside the sandbox workspace (/sandbox)
0
Expected: non-zero exit (e.g. 1) whenever the source path is rejected, so callers can detect the failure.
Environment
Device: Ubuntu 24.04 VM (x86_64) and DGX Spark (aarch64)
OS: Ubuntu 24.04 / Linux 6.8.0-124-generic
Architecture: x86_64 / aarch64
Node.js: v22.23.1
Docker: Docker Engine 29.5.3
OpenShell CLI: openshell 0.0.85
Reproduced on both x86_64 and aarch64. Security-relevant: the rejected paths include credential files (/var/lib/openshell/supervisor/creds.json), and an exit-0 rejection means automated tooling treating exit codes as ground truth records a successful download that never happened.
Logs
See the observed output above; full QA logs in NVIDIA/NemoClaw#7367.
Description
openshell sandbox downloadexits 0 when the download request is rejected because the source path is outside the sandbox workspace (/sandbox). The path-traversal guard correctly blocks the request and prints a user-facing error, but the failure is not propagated to the process exit code — scripts, test frameworks, and downstream tooling cannot detect the rejection.Downstream report with full QA reproduction: NVIDIA/NemoClaw#7367. NemoClaw has added caller-side defenses (NVIDIA/NemoClaw#7371, NVIDIA/NemoClaw#7416 — probe the source and verify an artifact was written), but those cannot fix the CLI's own exit code, which is what that issue's repro exercises.
Reproduction Steps
openshell sandbox download {sandbox-name} /etc/passwd /tmp/pecho $?/sandbox/../etc/passwdand/var/lib/openshell/supervisor/creds.json— same behavior.Observed:
Expected: non-zero exit (e.g. 1) whenever the source path is rejected, so callers can detect the failure.
Environment
Reproduced on both x86_64 and aarch64. Security-relevant: the rejected paths include credential files (
/var/lib/openshell/supervisor/creds.json), and an exit-0 rejection means automated tooling treating exit codes as ground truth records a successful download that never happened.Logs
See the observed output above; full QA logs in NVIDIA/NemoClaw#7367.