BUG-HUNT: [security] sandbox/get_path() absolute path bypass — all 4 sandbox implementations allow full filesystem escape #7474

Open
opened 2026-04-10 20:44:32 +00:00 by HAL9000 · 1 comment
Owner

Bug Report: Security — Sandbox Escape via Absolute Path in get_path()

Severity Assessment

  • Impact: Complete sandbox escape — actor can read/write any file on the filesystem
  • Likelihood: High — any tool input with an absolute path triggers this
  • Priority: Critical

Location

  • Files:
    • src/cleveragents/infrastructure/sandbox/git_worktree.pyGitWorktreeSandbox.get_path
    • src/cleveragents/infrastructure/sandbox/copy_on_write.pyCopyOnWriteSandbox.get_path
    • src/cleveragents/infrastructure/sandbox/overlay.pyOverlaySandbox.get_path
    • src/cleveragents/infrastructure/sandbox/transaction_sandbox.pyTransactionSandbox.get_path
  • Category: security (sandbox escape / path traversal)

Description

All four sandbox implementations protect against ".." path traversal components but do not block absolute paths. os.path.join discards everything to the left of an absolute component, so passing an absolute resource_path silently escapes the sandbox entirely.

Evidence

# Guard present in all four files:
if ".." in resource_path.split("/"):
    raise ValueError(f"Path traversal not allowed: {resource_path}")

return os.path.join(self._worktree_path, resource_path)
# OR: os.path.join(self._sandbox_path, resource_path)

Exploit:

sandbox.get_path("/etc/passwd")
# os.path.join("/sandbox/abc123", "/etc/passwd")  →  "/etc/passwd"
# Guard passes because ".." is not in ['', 'etc', 'passwd']
# Actor reads/writes /etc/passwd directly

The ".." check also misses backslash sequences (..\\) on Windows.

Expected Behavior

get_path() should always return a path that is strictly within the sandbox root, regardless of input format.

Actual Behavior

Absolute paths silently escape the sandbox. An actor can read/write any file the process has permission to access on the filesystem.

Suggested Fix

Replace the naive .. check with a resolved-path boundary check in all four implementations:

sandbox_root = self._worktree_path  # or _sandbox_path / _merged_dir
resolved = os.path.realpath(os.path.join(sandbox_root, resource_path))
if not (resolved == sandbox_root or
        resolved.startswith(sandbox_root + os.sep)):
    raise ValueError(
        f"Path traversal not allowed: {resource_path!r} resolves to {resolved!r}"
    )
return resolved

Category

security

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_, and @tdd_expected_fail to prove the bug exists before fixing it.


Automated by CleverAgents Bot
Supervisor: Bug Detection Pool | Agent: bug-hunt-pool-supervisor

## Bug Report: Security — Sandbox Escape via Absolute Path in `get_path()` ### Severity Assessment - **Impact**: Complete sandbox escape — actor can read/write any file on the filesystem - **Likelihood**: High — any tool input with an absolute path triggers this - **Priority**: Critical ### Location - **Files**: - `src/cleveragents/infrastructure/sandbox/git_worktree.py` — `GitWorktreeSandbox.get_path` - `src/cleveragents/infrastructure/sandbox/copy_on_write.py` — `CopyOnWriteSandbox.get_path` - `src/cleveragents/infrastructure/sandbox/overlay.py` — `OverlaySandbox.get_path` - `src/cleveragents/infrastructure/sandbox/transaction_sandbox.py` — `TransactionSandbox.get_path` - **Category**: security (sandbox escape / path traversal) ### Description All four sandbox implementations protect against `".."` path traversal components but do **not** block absolute paths. `os.path.join` discards everything to the left of an absolute component, so passing an absolute `resource_path` silently escapes the sandbox entirely. ### Evidence ```python # Guard present in all four files: if ".." in resource_path.split("/"): raise ValueError(f"Path traversal not allowed: {resource_path}") return os.path.join(self._worktree_path, resource_path) # OR: os.path.join(self._sandbox_path, resource_path) ``` **Exploit:** ```python sandbox.get_path("/etc/passwd") # os.path.join("/sandbox/abc123", "/etc/passwd") → "/etc/passwd" # Guard passes because ".." is not in ['', 'etc', 'passwd'] # Actor reads/writes /etc/passwd directly ``` The `".."` check also misses backslash sequences (`..\\`) on Windows. ### Expected Behavior `get_path()` should always return a path that is strictly within the sandbox root, regardless of input format. ### Actual Behavior Absolute paths silently escape the sandbox. An actor can read/write any file the process has permission to access on the filesystem. ### Suggested Fix Replace the naive `..` check with a resolved-path boundary check in all four implementations: ```python sandbox_root = self._worktree_path # or _sandbox_path / _merged_dir resolved = os.path.realpath(os.path.join(sandbox_root, resource_path)) if not (resolved == sandbox_root or resolved.startswith(sandbox_root + os.sep)): raise ValueError( f"Path traversal not allowed: {resource_path!r} resolves to {resolved!r}" ) return resolved ``` ### Category security ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it. --- **Automated by CleverAgents Bot** Supervisor: Bug Detection Pool | Agent: bug-hunt-pool-supervisor
HAL9000 added this to the v3.5.0 milestone 2026-04-10 21:38:35 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Critical — Security vulnerability that could allow unauthorized access, path traversal, or arbitrary code execution. Security bugs are always Critical priority.
  • Milestone: v3.5.0 (M6: Autonomy Hardening) — Security hardening and sandbox enforcement are core to this milestone
  • Story Points: 3 (M) — Bug fix with clear reproduction path and suggested fix
  • MoSCoW: Must Have — Security vulnerabilities must be fixed before any release
  • Type: Bug

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

Issue triaged by project owner: - **State**: Verified - **Priority**: Critical — Security vulnerability that could allow unauthorized access, path traversal, or arbitrary code execution. Security bugs are always Critical priority. - **Milestone**: v3.5.0 (M6: Autonomy Hardening) — Security hardening and sandbox enforcement are core to this milestone - **Story Points**: 3 (M) — Bug fix with clear reproduction path and suggested fix - **MoSCoW**: Must Have — Security vulnerabilities must be fixed before any release - **Type**: Bug --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#7474
No description provided.