-
Notifications
You must be signed in to change notification settings - Fork 254
Description
The Dockerfile has no USER instruction, so the daemon runs as root inside the container. Combined with a silent degradation path in the sandbox backend detection, this creates a privilege escalation risk under realistic deployment conditions.
The sandbox degradation path:
SandboxMode (the config value) and SandboxBackend (what's actually available at runtime) are independent. When mode is Enabled but no working backend is detected, wrap() falls through to wrap_passthrough() at sandbox.rs:466 — which runs the subprocess with no filesystem isolation. The only signal is a tracing::warn at sandbox.rs:219. Nothing in the health check, API status, or startup output surfaces this to an operator as a hard failure.
When this happens in Docker:
The Dockerfile installs bubblewrap, so under normal conditions the sandbox works. The risk has two distinct failure modes:
- bwrap absent from PATH (removed, different base image, stripped by policy):
detect_bubblewrap()atsandbox.rs:930returnsSandboxBackend::None,wrap()silently falls through towrap_passthrough(), and shell commands run as root with no OS-level containment. This is the silent-degradation path. - bwrap present but non-functional (CAP_SYS_ADMIN dropped, user namespaces disabled by container runtime):
detect_bubblewrap()runs a real probe (bwrap --ro-bind / / --proc /proc -- /usr/bin/true) atsandbox.rs:939-953, but on failure it returnsSandboxBackend::Bubblewrap { proc_supported: false }rather thanNone. Subsequentwrap_bubblewrap()invocations fail at spawn time (shell.rs:251), surfacing as tool errors to the LLM. This fails closed — no silent passthrough — but every shell command is broken with no clear startup diagnostic.
In both cases the container is running as root, so any containment gap (mode 1) or future bwrap CVE gives full root access.
Potential Fixes:
- Add
RUN useradd -ms /bin/bash spacebotandUSER spacebotbeforeENTRYPOINTin the Dockerfile. This is the most impactful single change — it limits blast radius regardless of sandbox state. - In
sandbox.rs, treatSandboxBackend::NonewithSandboxMode::Enabledas a fatal startup error (or a non-OK health check response), not a warn-and-continue. Operators deploying in Docker expect containment to be active. detect_bubblewrap()already runs a real probe (bwrap --ro-bind / / --proc /proc -- /usr/bin/true), but on failure it still returnsBubblewrap { proc_supported: false }. It should returnSandboxBackend::Nonewhen the probe fails entirely, not just demote theproc_supportedflag. A backend that can't create namespaces should not be reported as available.