BUG-HUNT: [security] Path Traversal Vulnerability in LegacyDataMigrator #3037

Open
opened 2026-04-05 04:12:13 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/legacy-migrator-path-traversal
  • Commit Message: fix(database): validate and sanitize project_path in LegacyDataMigrator to prevent path traversal
  • Milestone: v3.7.0
  • Parent Epic: #362

Bug Report: [security] — Path Traversal Vulnerability in LegacyDataMigrator

Severity Assessment

  • Impact: An attacker could read sensitive files or write malicious files to arbitrary locations on the filesystem, leading to information disclosure or remote code execution.
  • Likelihood: Low. An attacker would need to be able to control the project_path argument passed to the migrate_project_data method.
  • Priority: High

Location

  • File: src/cleveragents/infrastructure/database/legacy_migrator.py
  • Function/Class: LegacyDataMigrator.migrate_project_data
  • Lines: 47

Description

The migrate_project_data method constructs a path to the .cleveragents directory by appending to the user-controllable project_path argument. This is vulnerable to path traversal attacks. An attacker could provide a path like ../../.. to navigate up the directory tree and access arbitrary files.

Evidence

        def migrate_project_data(self, project_path: Path) -> bool:
            ...
            cleveragents_dir = project_path / ".cleveragents"

Expected Behavior

User-supplied paths should be sanitized and resolved to ensure they do not point to locations outside of the intended directory.

Actual Behavior

The project_path is used directly, allowing for path traversal.

Suggested Fix

Resolve the project_path to an absolute path and ensure it is within an expected base directory before using it.

from pathlib import Path

def migrate_project_data(self, project_path: Path) -> bool:
    # Define a safe base directory
    safe_base = Path('/path/to/safe/base').resolve()

    # Resolve the user-provided path
    resolved_path = project_path.resolve()

    # Check if the resolved path is within the safe base directory
    if not str(resolved_path).startswith(str(safe_base)):
        # Handle the error, e.g., raise an exception or log a warning
        raise ValueError("Invalid project path")

    cleveragents_dir = resolved_path / ".cleveragents"
    ...

Category

security

Subtasks

  • Investigate all call sites of migrate_project_data in LegacyDataMigrator to understand how project_path is sourced and passed
  • Define the safe base directory policy (e.g., user home, configured workspace root) and document it
  • Implement project_path.resolve() and a containment check against the safe base directory before any path operations
  • Raise a descriptive ValueError (or domain-specific exception) when the resolved path escapes the safe base, per fail-fast principle
  • Ensure the fix uses Path.is_relative_to() (Python ≥ 3.9) or an equivalent startswith check on the string representation of resolved paths
  • Update type annotations and docstrings to document the path validation contract
  • Tests (Behave): Add scenarios covering path traversal attempts (e.g., ../../etc/passwd), verifying an exception is raised and no filesystem access occurs outside the safe base
  • Tests (Behave): Add scenarios for valid paths within the safe base, verifying normal migration behaviour is preserved
  • Tests (Robot): Add integration test verifying the migrator rejects out-of-bounds paths end-to-end
  • Verify coverage >=97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly (fix(database): validate and sanitize project_path in LegacyDataMigrator to prevent path traversal), followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly (fix/legacy-migrator-path-traversal).
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage >= 97%.

Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/legacy-migrator-path-traversal` - **Commit Message**: `fix(database): validate and sanitize project_path in LegacyDataMigrator to prevent path traversal` - **Milestone**: v3.7.0 - **Parent Epic**: #362 ## Bug Report: [security] — Path Traversal Vulnerability in LegacyDataMigrator ### Severity Assessment - **Impact**: An attacker could read sensitive files or write malicious files to arbitrary locations on the filesystem, leading to information disclosure or remote code execution. - **Likelihood**: Low. An attacker would need to be able to control the `project_path` argument passed to the `migrate_project_data` method. - **Priority**: High ### Location - **File**: `src/cleveragents/infrastructure/database/legacy_migrator.py` - **Function/Class**: `LegacyDataMigrator.migrate_project_data` - **Lines**: 47 ### Description The `migrate_project_data` method constructs a path to the `.cleveragents` directory by appending to the user-controllable `project_path` argument. This is vulnerable to path traversal attacks. An attacker could provide a path like `../../..` to navigate up the directory tree and access arbitrary files. ### Evidence ```python def migrate_project_data(self, project_path: Path) -> bool: ... cleveragents_dir = project_path / ".cleveragents" ``` ### Expected Behavior User-supplied paths should be sanitized and resolved to ensure they do not point to locations outside of the intended directory. ### Actual Behavior The `project_path` is used directly, allowing for path traversal. ### Suggested Fix Resolve the `project_path` to an absolute path and ensure it is within an expected base directory before using it. ```python from pathlib import Path def migrate_project_data(self, project_path: Path) -> bool: # Define a safe base directory safe_base = Path('/path/to/safe/base').resolve() # Resolve the user-provided path resolved_path = project_path.resolve() # Check if the resolved path is within the safe base directory if not str(resolved_path).startswith(str(safe_base)): # Handle the error, e.g., raise an exception or log a warning raise ValueError("Invalid project path") cleveragents_dir = resolved_path / ".cleveragents" ... ``` ### Category security ## Subtasks - [ ] Investigate all call sites of `migrate_project_data` in `LegacyDataMigrator` to understand how `project_path` is sourced and passed - [ ] Define the safe base directory policy (e.g., user home, configured workspace root) and document it - [ ] Implement `project_path.resolve()` and a containment check against the safe base directory before any path operations - [ ] Raise a descriptive `ValueError` (or domain-specific exception) when the resolved path escapes the safe base, per fail-fast principle - [ ] Ensure the fix uses `Path.is_relative_to()` (Python ≥ 3.9) or an equivalent `startswith` check on the string representation of resolved paths - [ ] Update type annotations and docstrings to document the path validation contract - [ ] Tests (Behave): Add scenarios covering path traversal attempts (e.g., `../../etc/passwd`), verifying an exception is raised and no filesystem access occurs outside the safe base - [ ] Tests (Behave): Add scenarios for valid paths within the safe base, verifying normal migration behaviour is preserved - [ ] Tests (Robot): Add integration test verifying the migrator rejects out-of-bounds paths end-to-end - [ ] Verify coverage >=97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly (`fix(database): validate and sanitize project_path in LegacyDataMigrator to prevent path traversal`), followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly (`fix/legacy-migrator-path-traversal`). - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage >= 97%. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-05 04:12:22 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Confirmed
  • MoSCoW: Should Have

Valid finding verified during batch triage.


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

Issue triaged by project owner: - **State**: Verified - **Priority**: Confirmed - **MoSCoW**: Should Have Valid finding verified during batch triage. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Author
Owner

Label compliance fix applied:

  • Removed conflicting label: State/In Progress
  • Retained: State/Verified
  • Reason: Issue had two conflicting State/* labels simultaneously. Per CONTRIBUTING.md, only one State/* label is permitted. State/Verified is the more advanced state and has been retained.

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: ca-backlog-groomer

Label compliance fix applied: - Removed conflicting label: `State/In Progress` - Retained: `State/Verified` - Reason: Issue had two conflicting `State/*` labels simultaneously. Per CONTRIBUTING.md, only one `State/*` label is permitted. `State/Verified` is the more advanced state and has been retained. --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-backlog-groomer
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#3037
No description provided.