BUG-HUNT: [security] Path traversal vulnerability in 'context delete' and 'context clear' commands #3050

Open
opened 2026-04-05 04:17:54 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/security-context-path-traversal
  • Commit Message: fix(cli): sanitize context name to prevent path traversal in delete and clear commands
  • Milestone: v3.6.0
  • Parent Epic: (to be linked — see orphan note below)

Background and context

The context delete and context clear CLI commands accept a user-supplied name argument and use it directly to construct a filesystem path via ctx_base / name. No validation is performed to ensure the resolved path stays within the expected base directory. This allows a malicious user to supply a crafted name containing .. sequences to traverse up the directory tree and delete arbitrary files and directories on the system.

  • File: src/cleveragents/cli/commands/context.py
  • Functions: context_delete (line 707) and context_clear (line 775)
  • Severity: High — arbitrary file/directory deletion leading to data loss and system instability
  • Likelihood: Medium — requires intentional crafting of a malicious context name

Current behavior

Both context_delete and context_clear construct the target path as ctx_base / name without resolving or validating the result. A name such as ../../some/other/dir resolves to a path outside the context base directory, and shutil.rmtree (or item.unlink()) is then called on that arbitrary path.

# context_delete (line ~707)
target = ctx_base / name          # No traversal check
shutil.rmtree(target)             # Deletes arbitrary path

# context_clear (line ~775)
target = ctx_base / name          # No traversal check
for item in target.iterdir():
    if item.is_dir():
        shutil.rmtree(item)       # Deletes arbitrary subdirectories
    else:
        item.unlink()             # Deletes arbitrary files

Expected behavior

The resolved absolute path of target must be verified to be a subdirectory of ctx_base before any deletion occurs. If the resolved path escapes the base directory, the command must abort with a clear error message and a non-zero exit code.

Suggested Fix

ctx_base_resolved = ctx_base.resolve()
target = (ctx_base / name).resolve()
if not str(target).startswith(str(ctx_base_resolved) + "/"):
    typer.echo("Error: Invalid context name.", err=True)
    raise typer.Exit(code=1)

Acceptance criteria

  • context delete <name> rejects any name that resolves outside ctx_base with exit code 1 and a clear error message
  • context clear <name> rejects any name that resolves outside ctx_base with exit code 1 and a clear error message
  • Legitimate context names (no traversal) continue to work correctly
  • BDD scenarios cover the path traversal attack vector for both commands
  • No regression in existing context delete / context clear behaviour

Subtasks

  • Add path traversal guard to context_delete in src/cleveragents/cli/commands/context.py
  • Add path traversal guard to context_clear in src/cleveragents/cli/commands/context.py
  • Write Behave BDD scenarios for the path traversal rejection in both commands
  • Update integration tests (Robot Framework) if applicable
  • Verify all nox quality gates pass (nox -e lint, nox -e typecheck, nox -e unit_tests, nox -e coverage_report)

Definition of Done

  • Path traversal guard implemented in context_delete
  • Path traversal guard implemented in context_clear
  • BDD scenarios written and passing for both attack vectors
  • All nox stages pass
  • Coverage >= 97%
  • Commit created with message: fix(cli): sanitize context name to prevent path traversal in delete and clear commands
  • Code pushed to branch fix/security-context-path-traversal
  • PR merged and issue closed

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

## Metadata - **Branch**: `fix/security-context-path-traversal` - **Commit Message**: `fix(cli): sanitize context name to prevent path traversal in delete and clear commands` - **Milestone**: v3.6.0 - **Parent Epic**: *(to be linked — see orphan note below)* ## Background and context The `context delete` and `context clear` CLI commands accept a user-supplied `name` argument and use it directly to construct a filesystem path via `ctx_base / name`. No validation is performed to ensure the resolved path stays within the expected base directory. This allows a malicious user to supply a crafted name containing `..` sequences to traverse up the directory tree and delete arbitrary files and directories on the system. - **File**: `src/cleveragents/cli/commands/context.py` - **Functions**: `context_delete` (line 707) and `context_clear` (line 775) - **Severity**: High — arbitrary file/directory deletion leading to data loss and system instability - **Likelihood**: Medium — requires intentional crafting of a malicious context name ## Current behavior Both `context_delete` and `context_clear` construct the target path as `ctx_base / name` without resolving or validating the result. A name such as `../../some/other/dir` resolves to a path outside the context base directory, and `shutil.rmtree` (or `item.unlink()`) is then called on that arbitrary path. ```python # context_delete (line ~707) target = ctx_base / name # No traversal check shutil.rmtree(target) # Deletes arbitrary path # context_clear (line ~775) target = ctx_base / name # No traversal check for item in target.iterdir(): if item.is_dir(): shutil.rmtree(item) # Deletes arbitrary subdirectories else: item.unlink() # Deletes arbitrary files ``` ## Expected behavior The resolved absolute path of `target` must be verified to be a subdirectory of `ctx_base` before any deletion occurs. If the resolved path escapes the base directory, the command must abort with a clear error message and a non-zero exit code. ### Suggested Fix ```python ctx_base_resolved = ctx_base.resolve() target = (ctx_base / name).resolve() if not str(target).startswith(str(ctx_base_resolved) + "/"): typer.echo("Error: Invalid context name.", err=True) raise typer.Exit(code=1) ``` ## Acceptance criteria - [ ] `context delete <name>` rejects any `name` that resolves outside `ctx_base` with exit code 1 and a clear error message - [ ] `context clear <name>` rejects any `name` that resolves outside `ctx_base` with exit code 1 and a clear error message - [ ] Legitimate context names (no traversal) continue to work correctly - [ ] BDD scenarios cover the path traversal attack vector for both commands - [ ] No regression in existing `context delete` / `context clear` behaviour ## Subtasks - [ ] Add path traversal guard to `context_delete` in `src/cleveragents/cli/commands/context.py` - [ ] Add path traversal guard to `context_clear` in `src/cleveragents/cli/commands/context.py` - [ ] Write Behave BDD scenarios for the path traversal rejection in both commands - [ ] Update integration tests (Robot Framework) if applicable - [ ] Verify all nox quality gates pass (`nox -e lint`, `nox -e typecheck`, `nox -e unit_tests`, `nox -e coverage_report`) ## Definition of Done - [ ] Path traversal guard implemented in `context_delete` - [ ] Path traversal guard implemented in `context_clear` - [ ] BDD scenarios written and passing for both attack vectors - [ ] All nox stages pass - [ ] Coverage >= 97% - [ ] Commit created with message: `fix(cli): sanitize context name to prevent path traversal in delete and clear commands` - [ ] Code pushed to branch `fix/security-context-path-traversal` - [ ] PR merged and issue closed --- **Automated by CleverAgents Bot** Supervisor: Unknown | Agent: ca-new-issue-creator
freemo added this to the v3.6.0 milestone 2026-04-05 04:17:58 +00:00
Author
Owner

⚠️ Orphan Issue — Manual Linking Required

This issue was created without a known parent Epic. Per CONTRIBUTING.md, orphan issues are not permitted. A project maintainer must:

  1. Identify the appropriate parent Epic for this security fix (likely the Epic covering the context CLI command group or a security/hardening Epic).
  2. Create the dependency link so that this issue (#3050) blocks the parent Epic using Forgejo's dependency system.

The correct API call direction is:

# Issue #3050 BLOCKS the parent Epic
curl -s -X POST "https://git.cleverthis.com/api/v1/repos/cleveragents/cleveragents-core/issues/3050/blocks" \
  -H "Authorization: token <FORGEJO_PAT>" \
  -H "Content-Type: application/json" \
  -d '{"owner": "cleveragents", "repo": "cleveragents-core", "index": <PARENT_EPIC_NUMBER>}'

Please resolve this before moving the issue to State/Verified.


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

⚠️ **Orphan Issue — Manual Linking Required** This issue was created without a known parent Epic. Per CONTRIBUTING.md, orphan issues are **not permitted**. A project maintainer must: 1. Identify the appropriate parent Epic for this security fix (likely the Epic covering the `context` CLI command group or a security/hardening Epic). 2. Create the dependency link so that **this issue (#3050) blocks the parent Epic** using Forgejo's dependency system. The correct API call direction is: ```bash # Issue #3050 BLOCKS the parent Epic curl -s -X POST "https://git.cleverthis.com/api/v1/repos/cleveragents/cleveragents-core/issues/3050/blocks" \ -H "Authorization: token <FORGEJO_PAT>" \ -H "Content-Type: application/json" \ -d '{"owner": "cleveragents", "repo": "cleveragents-core", "index": <PARENT_EPIC_NUMBER>}' ``` Please resolve this before moving the issue to `State/Verified`. --- **Automated by CleverAgents Bot** Supervisor: Unknown | Agent: ca-new-issue-creator
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
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#3050
No description provided.