fix(tools): enforce workspace containment for read_file/write_file/edit_file#328
Open
sridhar-3009 wants to merge 1 commit into
Open
fix(tools): enforce workspace containment for read_file/write_file/edit_file#328sridhar-3009 wants to merge 1 commit into
sridhar-3009 wants to merge 1 commit into
Conversation
…it_file The built-in file tools resolved model-supplied paths to absolute host paths and read/wrote them with no check that the result stayed inside the project root. A model supplying an absolute path or enough ../ segments could reach any readable/writable file on the host — and on the non-interactive (task-worker / print-mode) runners that auto-approve tool calls, writes went through with no human prompt either. The existing validate_sandbox_path() boundary only ran inside the is_docker_sandbox_active() branch (disabled by default). Add a _check_workspace_containment() helper in each file tool that runs unconditionally, before the sandbox branch, and returns is_error=True with a clear message when the resolved path is not relative to context.cwd. The check uses Path.relative_to() so symlink escapes are caught after resolve() is called. Fixes HKUDS#310
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #310
The built-in file tools (
read_file,write_file,edit_file) resolved a model-supplied path to an absolute host path and then operated on it directly — with no check that the result stayed inside the project (workspace) root. A model that supplied an absolute path or enough../segments could reach any readable/writable file on the host.The existing
validate_sandbox_path()containment boundary only ran inside theis_docker_sandbox_active()branch, which is disabled by default. On the non-interactive runners (--task-worker, print-mode) that auto-approve tool calls, writes could go through with no human gate either.Fix: Add a
_check_workspace_containment(path, cwd)helper in each file tool that runs unconditionally, before the sandbox check, and returnsis_error=Truewith a clear message when the resolved path is not relative tocontext.cwd. The check callspath.relative_to(cwd.resolve())so symlink escapes are caught afterresolve()normalises the path.Test plan
read_filewith a relative../path that escapes the workspace — verify it returnsis_error=Truewith an "outside workspace root" message.read_filewith an absolute path outside the workspace (e.g./etc/hosts) — verify same denial.write_file/edit_filewith an out-of-workspace path — verify denial.validate_sandbox_pathwhen active (double-checked by the existing sandbox branch).