UAT: InlineToolExecutor._validate_paths() uses heuristic key-name matching — paths under non-standard keys bypass sandbox restriction #3744

Open
opened 2026-04-05 22:25:17 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/inline-executor-validate-all-paths
  • Commit Message: fix(inline-executor): validate all string values as paths, not just heuristic key names
  • Milestone: (backlog — no milestone assigned)
  • Parent Epic: #362

Backlog note: This issue was discovered during autonomous operation
on milestone v3.3.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.

Background and Context

InlineToolExecutor._validate_paths() in src/cleveragents/skills/inline_executor.py only validates file paths for input keys that end with _path, _file, or equal path. Paths passed under any other key name (e.g., filename, dir, directory, target, source) bypass the sandbox restriction entirely.

Current Behavior

_validate_paths() implementation:

def _validate_paths(self, input_data: dict[str, Any], sandbox_path: Path) -> str | None:
    for key, value in input_data.items():
        if not isinstance(value, str):
            continue
        # Heuristic: treat values that look like file paths
        if key.endswith("_path") or key == "path" or key.endswith("_file"):
            try:
                resolved = Path(value).resolve()
                sandbox_resolved = sandbox_path.resolve()
                if not str(resolved).startswith(str(sandbox_resolved)):
                    return (
                        f"Path '{value}' for key '{key}' escapes sandbox "
                        f"root '{sandbox_path}'"
                    )
            except (OSError, ValueError):
                return f"Invalid path '{value}' for key '{key}'"
    return None

An inline tool receiving {"filename": "/etc/passwd"} or {"dir": "/root"} or {"target": "/tmp/../etc/shadow"} would bypass this check entirely.

Expected Behavior

The spec states:

"Path restriction: Any file-path values in input_data are validated to reside within the sandbox root returned by SkillContext.get_sandbox_path()."

The spec says "any file-path values" — not just values under keys with specific naming patterns. All string values that resolve to absolute paths must be validated against the sandbox root, regardless of the key name used.

Impact

  • Malicious inline tools can access files outside the sandbox by using non-standard key names
  • The sandbox restriction is easily bypassed, undermining the security model
  • Violates the spec's "any file-path values" requirement

Steps to Reproduce

  1. Create an inline tool with code: open(input_data["filename"]).read()
  2. Execute with input_data = {"filename": "/etc/passwd"}
  3. Observe: no sandbox violation is raised, the file is read

Code Location

src/cleveragents/skills/inline_executor.py_validate_paths() method

What Was Tested

Code-level analysis of src/cleveragents/skills/inline_executor.py.

Subtasks

  • Implement heuristic-free path detection (check all string values that look like absolute paths)
  • Or: validate ALL string values that resolve to absolute paths against the sandbox
  • Add Behave tests for path bypass scenarios (e.g., keys filename, dir, directory, target, source)
  • Verify sandbox restriction works for all key names
  • Run nox (all default sessions), fix any errors
  • Verify coverage >= 97% via nox -s coverage_report

Definition of Done

This issue is complete when:

  • All string values that resolve to absolute paths are validated against the sandbox, regardless of key name
  • Unit and Behave tests cover path bypass scenarios for non-standard key names
  • nox -e unit_tests passes
  • All nox stages pass
  • Coverage >= 97%
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional details
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/inline-executor-validate-all-paths` - **Commit Message**: `fix(inline-executor): validate all string values as paths, not just heuristic key names` - **Milestone**: *(backlog — no milestone assigned)* - **Parent Epic**: #362 > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.3.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. ## Background and Context `InlineToolExecutor._validate_paths()` in `src/cleveragents/skills/inline_executor.py` only validates file paths for input keys that end with `_path`, `_file`, or equal `path`. Paths passed under any other key name (e.g., `filename`, `dir`, `directory`, `target`, `source`) bypass the sandbox restriction entirely. ## Current Behavior `_validate_paths()` implementation: ```python def _validate_paths(self, input_data: dict[str, Any], sandbox_path: Path) -> str | None: for key, value in input_data.items(): if not isinstance(value, str): continue # Heuristic: treat values that look like file paths if key.endswith("_path") or key == "path" or key.endswith("_file"): try: resolved = Path(value).resolve() sandbox_resolved = sandbox_path.resolve() if not str(resolved).startswith(str(sandbox_resolved)): return ( f"Path '{value}' for key '{key}' escapes sandbox " f"root '{sandbox_path}'" ) except (OSError, ValueError): return f"Invalid path '{value}' for key '{key}'" return None ``` An inline tool receiving `{"filename": "/etc/passwd"}` or `{"dir": "/root"}` or `{"target": "/tmp/../etc/shadow"}` would bypass this check entirely. ## Expected Behavior The spec states: > "**Path restriction**: Any file-path values in *input_data* are validated to reside within the sandbox root returned by `SkillContext.get_sandbox_path()`." The spec says "any file-path values" — not just values under keys with specific naming patterns. All string values that resolve to absolute paths must be validated against the sandbox root, regardless of the key name used. ## Impact - Malicious inline tools can access files outside the sandbox by using non-standard key names - The sandbox restriction is easily bypassed, undermining the security model - Violates the spec's "any file-path values" requirement ## Steps to Reproduce 1. Create an inline tool with code: `open(input_data["filename"]).read()` 2. Execute with `input_data = {"filename": "/etc/passwd"}` 3. Observe: no sandbox violation is raised, the file is read ## Code Location `src/cleveragents/skills/inline_executor.py` — `_validate_paths()` method ## What Was Tested Code-level analysis of `src/cleveragents/skills/inline_executor.py`. ## Subtasks - [ ] Implement heuristic-free path detection (check all string values that look like absolute paths) - [ ] Or: validate ALL string values that resolve to absolute paths against the sandbox - [ ] Add Behave tests for path bypass scenarios (e.g., keys `filename`, `dir`, `directory`, `target`, `source`) - [ ] Verify sandbox restriction works for all key names - [ ] Run `nox` (all default sessions), fix any errors - [ ] Verify coverage >= 97% via `nox -s coverage_report` ## Definition of Done This issue is complete when: - [ ] All string values that resolve to absolute paths are validated against the sandbox, regardless of key name - [ ] Unit and Behave tests cover path bypass scenarios for non-standard key names - [ ] `nox -e unit_tests` passes - [ ] All nox stages pass - [ ] Coverage >= 97% - [ ] A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional details - [ ] The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly - [ ] The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
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.

Blocks
#362 Epic: Security & Safety Hardening
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3744
No description provided.