Skip to content

fix(sandbox): block .. escapes when shell destinations do not exist - #66

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-management-2bf3
Draft

fix(sandbox): block .. escapes when shell destinations do not exist#66
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-management-2bf3

Conversation

@cursor

@cursor cursor Bot commented Aug 14, 2026

Copy link
Copy Markdown

Bug and impact

With sandbox workspace_only enabled (the documented default), a shell command whose destination does not exist yet was allowed if the string started with the workspace path. That lets the agent copy the SQLite store (sessions, memories, cron) out of the workspace, or write files elsewhere the process can write:

cp /home/user/.shellclaw/memory.db /home/user/.shellclaw/../../tmp/stolen.db

sandbox_exec only unshares namespaces and chdirs; it does not pivot_root. The allowlist is the filesystem gate.

Root cause

allowlist_path_is_under_workspace used realpath when the path existed, then fell back to a lexical prefix check. realpath fails for a missing file, so workspace/../../tmp/newfile matched the workspace prefix and was allowed. Existing destinations still went through realpath and were denied.

The file tool already walks to the first existing ancestor. The shell allowlist did not.

Fix

When realpath fails, walk parents with dirname until an existing directory resolves, then apply the workspace prefix check to that resolved ancestor. New files inside the workspace stay allowed.

Validation

  • Compiled tests/test_allowlist.c against the patched allowlist (this environment has no libcurl, so make test_allowlist cannot link the default -lcurl).
  • test_allowlist: all tests passed, including a new case that previously failed: workspace/../../tmp/sc_al_stolen_<pid> is blocked, while workspace/brand_new.txt is still allowed.
Open in WebView Automation

Lexical prefix matching treated workspace/../../tmp/newfile as inside
the workspace whenever realpath failed. sandbox_exec does not pivot_root,
so that was a real filesystem escape. Walk to the first existing ancestor
instead, matching tools/file.c.

Co-authored-by: esadrianno <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant