T09 · Insecure Skill Coding Practices
Warning
- Location
- script/main.py:49
- Finding
- Unbounded User-Controlled Regular Expression Evaluation Enables ReDoS<![CDATA[ ## Vulnerability Details **File Location**: `script/main.py`, lines 49, 67, 85, 105, 132, and 137 **Vulnerability Type**: Regular Expression Denial of Service (ReDoS) **Risk Level**: Medium ### Vulnerable Code ```python # line 49: match_test() result = re.search(pattern, text, flags) # line 67: find_all() matches = re.findall(pattern, text, flags) # line 85: find_iter() for i, match in enumerate(re.finditer(pattern, text, flags), 1): # line 105: groups() result = re.search(pattern, text, flags) # lines 132 and 137: substitute() result = re.sub(pattern, replacement, text, count=count, flags=flags) # Display the replacement count if count == 0: matches = re.findall(pattern, text, flags) ``` The affected values originate directly from command-line arguments: ```python match_parser.add_argument("pattern", help="Regular expression") match_parser.add_argument("text", help="Test text") find_parser.add_argument("pattern", help="Regular expression") find_parser.add_argument("text", help="Test text") iter_parser.add_argument("pattern", help="Regular expression") iter_parser.add_argument("text", help="Test text") groups_parser.add_argument("pattern", help="Regular expression") groups_parser.add_argument("text", help="Test text") sub_parser.add_argument("pattern", help="Regular expression") sub_parser.add_argument("replacement", help="Replacement content") sub_parser.add_argument("text", help="Original text") ``` ### Technical Analysis The application intentionally accepts arbitrary regular expressions and evaluates them using Python's backtracking `re` engine. No timeout, input-length restriction, process isolation, or resource limit is applied. Certain expressions containing ambiguous nested quantifiers can require exponential backtracking on a near-matching input. For example, `(a+)+$` evaluated against a long sequence of `a` characters followed by a nonmatching character can consume excessive CPU before determining that the match fails. ...[truncated 2034 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Enforce a hard execution deadline.** Run regex evaluation in a separate worker process and terminate that process when a short timeout is exceeded. A thread-based timeout is insufficient if the regex operation cannot be interrupted reliably. 2. **Apply operating-system resource limits.** Restrict worker CPU time and memory so a malicious expression cannot monopolize the host. 3. **Limit input sizes.** Reject patterns and input text exceeding conservative, documented limits. This reduces exposure but must not be treated as a complete ReDoS defense. 4. **Consider a safer regex engine.** Where feature compatibility permits, use an engine designed to provide linear-time matching or one that supports reliable match timeouts. 5. **Avoid duplicate evaluation.** For substitution, use an API that returns the replacement count as part of the same operation, such as `re.subn`, instead of invoking `re.sub` followed by `re.findall`: ```python result, replacements = re.subn( pattern, replacement, text, count=count, flags=flags, ) print(f"After replacement: {result}") print(f"Replaced {replacements} occurrence(s)") ``` 6. **Use heuristic checks only as defense in depth.** Detection of nested quantifiers and similar risky constructs may reject common dangerous patterns, but heuristics cannot reliably prove that an arbitrary backtracking expression is safe. 7. **Return a controlled error on timeout.** Report that evaluation exceeded the configured limit without automatically retrying the same expression. ]]>
