Skip to content

fix(tools): enforce workspace containment for read_file/write_file/edit_file#328

Open
sridhar-3009 wants to merge 1 commit into
HKUDS:mainfrom
sridhar-3009:fix/310-file-tool-workspace-containment
Open

fix(tools): enforce workspace containment for read_file/write_file/edit_file#328
sridhar-3009 wants to merge 1 commit into
HKUDS:mainfrom
sridhar-3009:fix/310-file-tool-workspace-containment

Conversation

@sridhar-3009

Copy link
Copy Markdown

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 the is_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 returns is_error=True with a clear message when the resolved path is not relative to context.cwd. The check calls path.relative_to(cwd.resolve()) so symlink escapes are caught after resolve() normalises the path.

# Before (no guard):
path = _resolve_path(context.cwd, arguments.path)
# … read/write directly …

# After:
path = _resolve_path(context.cwd, arguments.path)
contained, reason = _check_workspace_containment(path, context.cwd)
if not contained:
    return ToolResult(output=reason, is_error=True)
# … sandbox check, then read/write …

Test plan

  • read_file with a relative ../ path that escapes the workspace — verify it returns is_error=True with an "outside workspace root" message.
  • read_file with an absolute path outside the workspace (e.g. /etc/hosts) — verify same denial.
  • write_file / edit_file with an out-of-workspace path — verify denial.
  • Normal operations within the workspace continue to work unchanged.
  • Docker sandbox path still gets validated by validate_sandbox_path when active (double-checked by the existing sandbox branch).

…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
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.

[Bug]: Built-in file tools (read/write/edit) are not contained to the workspace root by default

1 participant