T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/search_docs.py:95
- Finding
- Regular Expression Denial of Service Through Unrestricted Search Patterns<![CDATA[ ## Vulnerability Details **File Location**: `scripts/search_docs.py`, lines 95–108 **Vulnerability Type**: Regular Expression Denial of Service (ReDoS) **Risk Level**: Medium ### Vulnerable Code ```python def regex_search(pattern: str, text: str) -> List[Tuple[int, str]]: """Search for regex matches, returning matching lines.""" try: regex = re.compile(pattern, re.IGNORECASE) except re.error as e: print(f"Invalid regex pattern: {e}", file=sys.stderr) return [] lines = text.split('\n') matches = [] for i, line in enumerate(lines): if regex.search(line): matches.append((i + 1, line.strip())) ``` The pattern originates from the positional `query` command-line argument and is passed to this function when the user selects `--mode regex`: ```python search_fn = keyword_search if mode == "keyword" else regex_search ... matches = search_fn(query, article.content) ``` ### Technical Analysis The application compiles and evaluates an unrestricted, user-supplied regular expression using Python's backtracking `re` engine. Although malformed expressions are caught, syntactically valid patterns with nested or ambiguous quantifiers can require exponential processing time on crafted input. For example, a pattern such as: ```text (a+)+$ ``` can cause catastrophic backtracking when evaluated against a sufficiently long documentation line consisting of many `a` characters followed by a nonmatching character. There is no pattern-complexity validation, input-length limit, matching timeout, or process-level resource boundary. The risk applies when the query is controlled by an untrusted caller, including cases where an agent invokes the script using search terms taken from an untrusted prompt. Exploitation also requires a sufficiently adverse line in the searched Markdown corpus, whether naturally present or attacker-controlled. ### Attack Path 1. The attacker supplies a pathological r ...[truncated 1297 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Prefer a non-backtracking regular-expression engine such as RE2 for searches involving untrusted patterns. 2. If regex support is not required, remove `--mode regex` and retain literal keyword searching. 3. If using a regex implementation that supports timeouts, enforce a short per-match timeout and treat timeout failures as rejected searches. 4. Reject patterns containing risky constructs such as nested quantifiers, ambiguous alternation under repetition, and excessive repetition depth. Pattern filtering should be defense in depth rather than the sole control. 5. Impose conservative limits on: - Pattern length. - Number of files and lines searched. - Maximum line length passed to the regex engine. - Total search execution time. 6. Run regex searches in an isolated subprocess with CPU and wall-clock limits. Terminate the subprocess when those limits are exceeded. 7. Ensure agent workflows do not automatically place untrusted prompt content into regex mode. Use keyword mode by default and require explicit trusted-user approval for regex searches. 8. Add regression tests using known pathological patterns, including `(a+)+$`, against long near-matching input to verify that execution is rejected or terminated within the configured time limit. ]]>
