From 361c89adddf1de38495f3a95dd0ac275999fd80d Mon Sep 17 00:00:00 2001 From: CleverThis Date: Fri, 8 May 2026 09:28:50 +0000 Subject: [PATCH] fix(security): fix file_tools.py validate_path startswith bypass #7478 - Add CHANGELOG.md Security section entry under [Unreleased] for the validate_path path traversal prefix-collision bypass vulnerability. - Update CONTRIBUTORS.md with HAL 9000 contribution description for issue #7478 (file_tools.py validate_path startswith bypass fix). - Fix BDD test scenario tag from @tdd_issue_7558 to @tdd_issue_7478 in features/tool_builtins.feature. ISSUES CLOSED: #7478 --- CHANGELOG.md | 12 ++++++++++++ CONTRIBUTORS.md | 1 + features/tool_builtins.feature | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c694525c..22b306c53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,6 +107,18 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ### Security +- **file_tools.py `validate_path` startswith bypass** (#7478): Replaced the insecure + `str(target).startswith(str(root))` prefix check in + `cleveragents.tool.builtins.file_tools.validate_path()` with a proper + `Path.relative_to(root)` containment guard. The old string-prefix approach was + vulnerable to a path-traversal bypass: a sandbox root of ``/tmp/sandbox`` combined + with a crafted path resolving to ``/tmp/sandbox-evil`` would incorrectly pass the + ``startswith`` check because the resolved target string literally begins with the + root string. The new implementation uses Python's built-in ``Path.relative_to()`` + which correctly rejects any target that is not *within* the sandbox directory + hierarchy, including the prefix-collision case where a sibling directory name + shadowed (i.e., was a string prefix of) the sandbox name. + - **aiohttp upgraded to >=3.13.4 to remediate CVE-2026-34513 and CVE-2026-34515** (#1549, #1544): Added an explicit `aiohttp>=3.13.4` dependency constraint to `pyproject.toml` to remediate two high-severity open redirect vulnerabilities. Both CVEs affect the CleverAgents platform's diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 358d21b58..aeb390851 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -19,6 +19,7 @@ Below are some of the specific details of various contributions. * HAL 9000 has contributed the plan concurrency race-condition fix (#7989): wired `LockService` into the plan lifecycle, guarding `execute_plan()` and `apply_plan()` with plan-level advisory locks and unique per-invocation owner identities to prevent silent concurrent state corruption. * HAL 9000 has contributed the bug-hunt-pool-supervisor non-blocking tracking fix: updated step 5 to be best-effort and added rule 9 to prevent the automation-tracking-manager call from blocking the main supervisor loop. * HAL 9000 has contributed the plugin entry point security hardening fix (#7476): enforced entry point allowlist validation before importing plugin modules to prevent malicious plugin loading. +* HAL 9000 has contributed the `file_tools.py validate_path` path traversal startswith bypass fix (#7478): replaced the insecure `str(target).startswith(str(root))` prefix check with a proper `Path.relative_to(root)` containment guard to correctly reject sibling-directory prefix-collision escape paths. * HAL 9000 has contributed the benchmark workflow separation (#9040): moved the benchmark-regression job out of the default PR workflow into a dedicated scheduled workflow, reducing median PR CI turnaround time from 99-132 minutes to under 30 minutes. * HAL 9000 has contributed the agent-evolution-pool-supervisor PR metadata assignment (#7888): the supervisor now automatically looks up the Type/Automation label and earliest open milestone before dispatching improvement PR creation workers, ensuring all generated improvement PRs have correct Type labels and milestone assignments. * HAL 9000 has contributed the decision recording hook for the Strategize phase (issue #8522): captures every decision point with question, chosen option, alternatives, confidence, rationale, and full context snapshot for replay and correction. diff --git a/features/tool_builtins.feature b/features/tool_builtins.feature index ea7f94141..a20cd2643 100644 --- a/features/tool_builtins.feature +++ b/features/tool_builtins.feature @@ -160,7 +160,7 @@ Feature: Built-in File Tools Then the tool result should not be successful And the tool result error should mention "traversal" - @tdd_issue @tdd_issue_7558 + @tdd_issue @tdd_issue_7478 Scenario: Path traversal with sandbox name prefix collision is rejected Given a temporary sandbox directory And a sibling directory with a name that is a prefix of the sandbox name -- 2.52.0