Skip to content

security: mitigate ReDoS in proxy view_request regex search#876

Open
Sunil56224972 wants to merge 1 commit into
usestrix:mainfrom
Sunil56224972:pr2-redos
Open

security: mitigate ReDoS in proxy view_request regex search#876
Sunil56224972 wants to merge 1 commit into
usestrix:mainfrom
Sunil56224972:pr2-redos

Conversation

@Sunil56224972

Copy link
Copy Markdown

Summary

The _format_search_hits() helper in strix/tools/proxy/tools.py compiles a user-supplied regex pattern and runs it against HTTP response bodies via finditer(). A crafted pattern with catastrophic backtracking (e.g. (a+)+$) can hang the agent's event loop indefinitely since this runs under the shared _CAIDO_CALL_LOCK.

Severity: Medium

While the regex pattern comes from the AI agent (not directly from an external attacker), a malicious target application could return content specifically designed to trigger catastrophic backtracking against common patterns the agent might use.

Mitigations applied

  1. Truncate search content to 1 MiB before running the regex — this bounds worst-case CPU time even for pathological patterns, since backtracking complexity is proportional to input size
  2. Catch RecursionError during finditer() — some patterns hit Python's recursion limit on large inputs
  3. Warn the caller when content was truncated so results are understood as partial

Files changed

  • strix/tools/proxy/tools.py

Testing

  • Verified existing search behavior is preserved for normal patterns and content sizes
  • The 20-hit cap continues to work as before
  • Content >1 MiB is now safely truncated with a warning in the response

The _format_search_hits() helper compiles a user-supplied regex
pattern and runs it against HTTP response bodies via finditer().
A crafted pattern with catastrophic backtracking (e.g. '(a+)+$')
can hang the agent's event loop indefinitely since this runs
under the shared _CAIDO_CALL_LOCK.

Mitigations applied:
1. Truncate the search content to 1 MiB before running the regex.
   This bounds the worst-case CPU time even for pathological patterns,
   since backtracking complexity is at least proportional to input size.
2. Catch RecursionError during finditer() -- some patterns hit
   Python's recursion limit on large inputs.
3. Warn the caller when content was truncated so results are
   understood as partial.
@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR attempts to mitigate regex denial of service in proxy request searching.

  • Limits the searched content to 1,048,576 characters.
  • Reports a warning when content is truncated.
  • Converts regex execution errors and recursion failures into structured tool errors.

Confidence Score: 3/5

This PR is not safe to merge until regex execution receives an enforceable runtime bound or is moved to an execution context that can be terminated.

The synchronous Python regex search can perform catastrophic backtracking on adversarial content far below the new 1 MiB cap, blocking the event loop before asynchronous timeout handling can run.

Files Needing Attention: strix/tools/proxy/tools.py

Security Review

The new input-length cap does not impose an execution-time bound, so catastrophic regex backtracking remains able to block the event loop on inputs much smaller than the cap.

Important Files Changed

Filename Overview
strix/tools/proxy/tools.py Adds truncation and exception handling around proxy regex searches, but leaves the targeted CPU-exhaustion path reachable because synchronous backtracking has no runtime bound.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
strix/tools/proxy/tools.py:320-323
**Regex execution remains unbounded**

When an agent searches an adversarial HTTP body with a catastrophic-backtracking expression such as `(a+)+$`, truncating the body to 1 MiB still permits exponential work on much shorter inputs, causing the synchronous search to block the event loop indefinitely; catching exceptions after `finditer()` returns does not enforce an execution bound.

**How this was verified:** `view_request` passes the agent-supplied pattern and decoded HTTP content directly to synchronous `regex.finditer()` without a regex timeout or interruptible execution boundary.

Reviews (1): Last reviewed commit: "security: mitigate ReDoS in proxy view_r..." | Re-trigger Greptile

Comment on lines +320 to 323
_MAX_SEARCH_LEN = 1_048_576 # 1 MiB
search_content = content[:_MAX_SEARCH_LEN]
truncated = len(content) > _MAX_SEARCH_LEN

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Regex execution remains unbounded

When an agent searches an adversarial HTTP body with a catastrophic-backtracking expression such as (a+)+$, truncating the body to 1 MiB still permits exponential work on much shorter inputs, causing the synchronous search to block the event loop indefinitely; catching exceptions after finditer() returns does not enforce an execution bound.

How this was verified: view_request passes the agent-supplied pattern and decoded HTTP content directly to synchronous regex.finditer() without a regex timeout or interruptible execution boundary.

Knowledge Base Used: Tools Overview

Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/tools/proxy/tools.py
Line: 320-323

Comment:
**Regex execution remains unbounded**

When an agent searches an adversarial HTTP body with a catastrophic-backtracking expression such as `(a+)+$`, truncating the body to 1 MiB still permits exponential work on much shorter inputs, causing the synchronous search to block the event loop indefinitely; catching exceptions after `finditer()` returns does not enforce an execution bound.

**How this was verified:** `view_request` passes the agent-supplied pattern and decoded HTTP content directly to synchronous `regex.finditer()` without a regex timeout or interruptible execution boundary.

**Knowledge Base Used:** [Tools Overview](https://app.greptile.com/strix-org-3/-/custom-context/knowledge-base/usestrix/strix/-/docs/tools-overview.md)

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant