BUG-HUNT: [security] Potential ReDoS vulnerability in 'tool list' command #3028

Open
opened 2026-04-05 04:06:08 +00:00 by freemo · 2 comments
Owner

Metadata

  • Commit Message: fix(cli): add ReDoS protection to tool list regex filter
  • Branch: fix/redos-tool-list-regex
  • Milestone: v3.6.0

Background and Context

The agents tool list command accepts an optional user-supplied regex pattern to filter tool names. This pattern is compiled and executed by Python's re module without any validation, sanitisation, or timeout. A carefully crafted regex pattern — such as (a+)+$ — can cause catastrophic backtracking in the regex engine, consuming excessive CPU and effectively hanging the CLI process indefinitely. This is a well-known class of vulnerability called Regular Expression Denial of Service (ReDoS).

While the likelihood of accidental exploitation is low (it requires a user to intentionally supply a malicious pattern), the impact is a complete denial of service for the affected user session. Given that CleverAgents is a CLI tool that may be scripted or integrated into automated pipelines, this warrants a medium-priority fix.

Current Behavior

The list_tools function in src/cleveragents/cli/commands/tool.py (lines 382–394) compiles and executes a user-supplied regex without any timeout or complexity guard:

if regex:
    try:
        pattern = re.compile(regex)
    except re.error as exc:
        console.print(f"[red]Invalid regex pattern:[/red] {regex}")
        raise typer.Abort() from exc

    def _get_name(t: Any) -> str:
        if isinstance(t, dict):
            return str(t.get("name", ""))
        return str(getattr(t, "name", ""))

    tools = [t for t in tools if pattern.search(_get_name(t))]

A user running agents tool list --filter "(a+)+$" against a list of tool names could cause the CLI to hang indefinitely.

Expected Behavior

The CLI should protect against ReDoS by either:

  1. Executing the regex match with a timeout (e.g., using signal-based timeout on Unix, or a thread-based timeout), OR
  2. Using the re2 / google-re2 library which guarantees linear-time matching and is immune to ReDoS, OR
  3. Detecting and rejecting pathologically complex patterns before execution.

The command should complete in bounded time regardless of the regex pattern supplied.

Acceptance Criteria

  • The agents tool list --filter <pattern> command cannot be made to hang indefinitely by any user-supplied regex pattern.
  • If a timeout-based approach is used, the CLI prints a clear error message (e.g., [red]Regex pattern timed out — pattern may be too complex[/red]) and exits cleanly (non-zero exit code) rather than hanging.
  • If a safe-regex library (e.g., google-re2) is used, the dependency is added to pyproject.toml and the import is updated accordingly.
  • All existing agents tool list filter behaviour is preserved for safe patterns.
  • Unit tests (Behave) cover the ReDoS scenario: a known catastrophic pattern against a matching string must not hang (verified via timeout in the test).
  • All nox sessions pass (nox).
  • Coverage remains ≥ 97% (nox -e coverage_report).

Supporting Information

Subtasks

  • Investigate and select the most appropriate ReDoS mitigation strategy (timeout vs. google-re2 vs. pattern complexity check)
  • Implement the chosen mitigation in src/cleveragents/cli/commands/tool.py list_tools
  • Add/update type annotations to satisfy Pyright (nox -e typecheck)
  • Tests (Behave): Add scenario for ReDoS pattern — assert command completes within bounded time
  • Tests (Behave): Add scenario confirming safe patterns still filter correctly
  • Tests (Robot): Add integration test for agents tool list --filter with a complex pattern
  • Update pyproject.toml if a new dependency is introduced
  • Verify coverage ≥ 97% via nox -e 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(cli): add ReDoS protection to tool list regex filter), 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/redos-tool-list-regex).
  • 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: Unknown | Agent: ca-new-issue-creator

## Metadata - **Commit Message**: `fix(cli): add ReDoS protection to tool list regex filter` - **Branch**: `fix/redos-tool-list-regex` - **Milestone**: v3.6.0 ## Background and Context The `agents tool list` command accepts an optional user-supplied regex pattern to filter tool names. This pattern is compiled and executed by Python's `re` module without any validation, sanitisation, or timeout. A carefully crafted regex pattern — such as `(a+)+$` — can cause catastrophic backtracking in the regex engine, consuming excessive CPU and effectively hanging the CLI process indefinitely. This is a well-known class of vulnerability called Regular Expression Denial of Service (ReDoS). While the likelihood of accidental exploitation is low (it requires a user to intentionally supply a malicious pattern), the impact is a complete denial of service for the affected user session. Given that CleverAgents is a CLI tool that may be scripted or integrated into automated pipelines, this warrants a medium-priority fix. ## Current Behavior The `list_tools` function in `src/cleveragents/cli/commands/tool.py` (lines 382–394) compiles and executes a user-supplied regex without any timeout or complexity guard: ```python if regex: try: pattern = re.compile(regex) except re.error as exc: console.print(f"[red]Invalid regex pattern:[/red] {regex}") raise typer.Abort() from exc def _get_name(t: Any) -> str: if isinstance(t, dict): return str(t.get("name", "")) return str(getattr(t, "name", "")) tools = [t for t in tools if pattern.search(_get_name(t))] ``` A user running `agents tool list --filter "(a+)+$"` against a list of tool names could cause the CLI to hang indefinitely. ## Expected Behavior The CLI should protect against ReDoS by either: 1. Executing the regex match with a timeout (e.g., using `signal`-based timeout on Unix, or a thread-based timeout), OR 2. Using the `re2` / `google-re2` library which guarantees linear-time matching and is immune to ReDoS, OR 3. Detecting and rejecting pathologically complex patterns before execution. The command should complete in bounded time regardless of the regex pattern supplied. ## Acceptance Criteria - [ ] The `agents tool list --filter <pattern>` command cannot be made to hang indefinitely by any user-supplied regex pattern. - [ ] If a timeout-based approach is used, the CLI prints a clear error message (e.g., `[red]Regex pattern timed out — pattern may be too complex[/red]`) and exits cleanly (non-zero exit code) rather than hanging. - [ ] If a safe-regex library (e.g., `google-re2`) is used, the dependency is added to `pyproject.toml` and the import is updated accordingly. - [ ] All existing `agents tool list` filter behaviour is preserved for safe patterns. - [ ] Unit tests (Behave) cover the ReDoS scenario: a known catastrophic pattern against a matching string must not hang (verified via timeout in the test). - [ ] All nox sessions pass (`nox`). - [ ] Coverage remains ≥ 97% (`nox -e coverage_report`). ## Supporting Information - **File**: `src/cleveragents/cli/commands/tool.py` - **Function**: `list_tools` - **Lines**: 382–394 - **Related issue (same security category)**: #2995 — Default server host binds to all interfaces - **Related issue (same security category)**: #2590 — Minimal URI validation in ACMS vocabulary models - **ReDoS reference**: https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS - **Example catastrophic pattern**: `(a+)+$` matched against `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"` ## Subtasks - [ ] Investigate and select the most appropriate ReDoS mitigation strategy (timeout vs. `google-re2` vs. pattern complexity check) - [ ] Implement the chosen mitigation in `src/cleveragents/cli/commands/tool.py` `list_tools` - [ ] Add/update type annotations to satisfy Pyright (`nox -e typecheck`) - [ ] Tests (Behave): Add scenario for ReDoS pattern — assert command completes within bounded time - [ ] Tests (Behave): Add scenario confirming safe patterns still filter correctly - [ ] Tests (Robot): Add integration test for `agents tool list --filter` with a complex pattern - [ ] Update `pyproject.toml` if a new dependency is introduced - [ ] Verify coverage ≥ 97% via `nox -e 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(cli): add ReDoS protection to tool list regex filter`), 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/redos-tool-list-regex`). - 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: Unknown | Agent: ca-new-issue-creator
freemo added this to the v3.6.0 milestone 2026-04-05 04:06:47 +00:00
Author
Owner

⚠️ Orphan Issue — Manual Linking Required

This issue was created without a parent Epic because no open security or hardening Epic currently exists in the repository. The two open Epics found are:

  • #2810 — CI Quality Gates Restoration (marked State/Duplicate)
  • #2749 — CI Observability and Agent-Accessible Diagnostics (unrelated scope)

Action required for a maintainer: Please either:

  1. Create a new Type/Epic for security/hardening work and link this issue as a child (this issue blocks the parent Epic), OR
  2. Link this issue to an appropriate existing Epic once one is created.

Per CONTRIBUTING.md, orphan issues are not permitted. This issue must be linked to a parent Epic before it moves beyond State/Unverified.


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

⚠️ **Orphan Issue — Manual Linking Required** This issue was created without a parent Epic because no open security or hardening Epic currently exists in the repository. The two open Epics found are: - #2810 — CI Quality Gates Restoration (marked `State/Duplicate`) - #2749 — CI Observability and Agent-Accessible Diagnostics (unrelated scope) **Action required for a maintainer**: Please either: 1. Create a new `Type/Epic` for security/hardening work and link this issue as a child (this issue **blocks** the parent Epic), OR 2. Link this issue to an appropriate existing Epic once one is created. Per CONTRIBUTING.md, orphan issues are not permitted. This issue must be linked to a parent Epic before it moves beyond `State/Unverified`. --- **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#3028
No description provided.