Replies: 1 comment
|
0.1.1-rc.2 also has the issue. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Date: 2026-08-25
Components:
@deepseek-ai/dsh-sandbox-local(macOS Seatbelt backend),@deepseek-ai/dsh-sandbox(policy helpers)Tested version:
@deepseek-ai/dsh0.1.0-rc.7Environment: macOS 26.5.1 (Build 25F80, arm64), Docker Desktop 4.68.0, default
workspace-writesession;read-onlyreproduced via the identical profileMethodology: benign probes only (expected-to-fail canary writes + read-only APIs). No container created, no signature requested, no file created or modified outside temp areas.
Summary
The DSH process sandbox on macOS is implemented as a Seatbelt profile whose only deny rule is
(deny file-write*), confining filesystem writes to the workspace root and platform tempdirectories. Every other operation axis — including outbound networking — remains under
(allow default).A unix-domain-socket
connect(2)is not afile-write*operation. Consequently, the sandboxedagent process cannot write a single byte outside its workspace, yet it can connect without
restriction to any local service listening as the same OS user. This report verifies two such
channels:
~/.docker/run/docker.sock): read-only API calls succeed(
GET /_ping→OK;GET /v1.41/versionreturns daemon metadata). With API access, anagent can issue
POST /containers/createwith a host bind-mount and execute inside thatcontainer, obtaining arbitrary read/write/execute on the host as the user — the entire
file-write fence becomes moot.
SSH_AUTH_SOCK): the agent protocol connectssuccessfully. Once the user has identities loaded, sandboxed code can request signature
operations through the standard protocol and act under the user's identity.
Both modes are affected. The writable-roots helper
writableRoots(policy)returns anon-empty list only when
mode === "workspace-write"; the profile generated forread-onlydiffers from
workspace-writeby exactly one file-write allowlist line. The outbound-networkaxis carries no rules in either mode, so socket behavior is identical.
Why it matters
privileges are standard on developer machines: container runtimes, credential agents,
language servers. When a sandbox constrains only direct file writes, these components form
equivalent channels around the fence.
arbitrary execution under the user's privileges. The net effect of this finding equals
bypassing the entire file-write fence; we suggest treating it as sandbox-escape-class.
leaves no filesystem trace. Whenever loaded identities exist in the user session, sandboxed
code can perform identity impersonation.
read-onlydoes not reduce this exposure. The mode denies all file writes but adds noconstraint on local IPC or network egress; for socket-based channels, the strictest mode has
the same boundary as the default mode.
Root cause
The single place the profile is built (
dsh-sandbox-local/lib/index.js):Where writable roots come from (
dsh-sandbox/lib/index.js):Two conclusions follow:
(allow default).writes; socket behavior is mode-independent.
Scoping-gap classification
Contrast experiment executed back-to-back in one session:
$HOMEOperation not permitted)file-write*rule exists and is enforcedconnect()to docker.sock followed by GETA bypass implies a denial followed by evasion. Here the first attempt succeeds because no rule
governs that axis. The correct classification is therefore missing restriction scope, and
the fix must land at the policy-generation layer; blocking individual daemons does not converge
this class of issues.
Reproduction
Option A: inside any DSH session (applies to
workspace-writeandread-only)Three commands suffice:
Observed output (2026-08-25):
Full automation script in Appendix A (also saved as
poc/poc.sh), including socketauto-discovery, verdict output, and cleanup.
Option B: reproduce
read-onlyfrom a plain terminal (no DSH session required)Seatbelt cannot nest, so outside a DSH session feed DSH's exact read-only profile to
sandbox-exec:Under the same profile, the first command denied while the second succeeds completes the proof
for read-only mode. Parameterized script in Appendix B (also saved as
poc/poc-readonly.sh).Impact projection (not executed)
The following paths are stated to justify severity only; none were performed during testing:
-v /:/hostbind-mount and execute within it,yielding arbitrary host read/write/execute as the user.
challenges, affecting commits, tags, pushes, and any other artifact accepting SSH signatures.
Proposal
In priority order:
by default and provide an explicit allowlist mechanism sourced from the same shared helper
as
writableRoots, preventing drift between the fs fence and the socket fence. Packagemanagers and similar legitimate cases can retain exits via explicit configuration.
neutralize
SSH_AUTH_SOCK,DOCKER_HOST,GPG_AGENT_INFO, etc. This complementskernel-level rules and covers backends where socket filtering is costlier to implement
(Windows ACL).
reachable under the current mode and surface them in the trust footer (e.g. “workspace-write:
local Docker socket is reachable”).
(currently filesystem writes only) and which remain open (network, local IPC), enabling
informed decisions on hosts with privileged local services.
Fixes 1+2 combined close the verified cases and the general class; 3+4 improve operator
awareness for residual environments.
Trade-offs / open questions
legitimate consumers (e.g. package managers reaching their cache services); whether users may
extend the list via configuration must be weighed against default posture.
across OS versions; probe-stage verification that the kernel accepts the rules can reuse the
existing fail-closed probing mechanism.
differ in their ability to constrain local IPC; if only macOS is converged, the documentation
should note per-platform differences.
Test methodology note
Verification used only benign canaries (writes expected to fail) and read-only API calls
(
/_ping,/version,ssh-add -l). No container was created or started, no signature wasrequested, nothing was created or modified outside temp areas, and all temporary artifacts were
removed. Findings should reproduce identically on any macOS host with Docker Desktop under a
default
workspace-writeorread-onlysession.Appendix A:
poc/poc.sh(in-session PoC)Click to expand full script
Observed output (2026-08-25):
Appendix B:
poc/poc-readonly.sh(standalone terminal PoC, read-only focused)Click to expand full script
All reactions