From soundcheck
Checks regex patterns for ReDoS (CWE-1333) vulnerabilities when applied to user input. Flags catastrophic backtracking risks and suggests fixes like atomic groups, timeouts, RE2 for Python, Go, Java.
npx claudepluginhub thejefflarson/soundcheck --plugin soundcheckThis skill uses the workspace's default tool permissions.
Protects against Regular Expression Denial of Service where a crafted input causes
Detects ReDoS vulnerabilities via catastrophic backtracking in regex patterns on user-controlled input. Audits JS/TS/Python/Ruby/PHP/Java code and measures growth rates.
Writes, debugs, and explains regex patterns emphasizing readability, performance optimization, edge cases, testing strategies, and regex alternatives. Activates on mentions of regex, regular expressions, pattern matching, text parsing, extraction, or format validation.
DEPRECATED: Generates, explains, and tests regex patterns from positive/negative examples with Python/JavaScript code. Retained for reference only.
Share bugs, ideas, or general feedback.
Protects against Regular Expression Denial of Service where a crafted input causes catastrophic backtracking in regex engines. A single malicious string can pin a CPU core for minutes or hours, taking down the service.
re.match(r"(a+)+$", user_input) — nested quantifiers cause exponential backtrackingPattern.compile("(.*a){20}") — overlapping alternation with repetition/^([\w.]+)+@/ .test(email) — common email regex with catastrophic backtrackingRegex::new(r"(\d+\.?\d*)+") — ambiguous quantifier nesting on numeric inputFlag the vulnerable regex and explain the risk. Show the secure pattern below as a suggested fix. Then continue with the original task.
Secure patterns:
(a+)+ → a+(?>a+) or a++# Python — use re2 or set a match timeout
import re
# Bad: re.match(r"(a+)+$", user_input)
# Good: anchor and simplify
re.match(r"a+$", user_input)
# Or use google-re2 which guarantees linear time
// Go — regexp package uses RE2 engine (safe by default)
// Go's regexp CANNOT have catastrophic backtracking
r := regexp.MustCompile(`a+$`)
// Java — no built-in protection; simplify or add timeout
Pattern p = Pattern.compile("a+$"); // simplified, no nesting
Matcher m = p.matcher(input);
// For complex patterns, run in a thread with a timeout
Why this works: Removing nested quantifiers eliminates the exponential state space. RE2-based engines (Go, google-re2) guarantee linear-time matching by disallowing backtracking entirely.
(a+)+, (a*)*, (a|a)+, or (a+b?)+