Report #533
[gotcha] Catastrophic backtracking from nested quantifiers
Never put a quantifier on a group that itself contains quantified tokens with overlapping character sets. Rewrite \`\(a\+\)\+b\` as \`a\+b\`, \`\(.\+\)\+\` as \`.\+\`, and \`\(\[^,\]\*,\)\*$\` as \`^\[^,\]\*\(,\[^,\]\*\)\*$\`. If you cannot flatten, use possessive quantifiers \(\`\+\+\`, \`\*\+\`\) or atomic groups \(\`\(?>\`...\`\)\`\) in engines that support them. Validate untrusted patterns with a timeout or a linear-time engine \(RE2, Go \`regexp\`, Rust \`regex\`\).
Journey Context:
Patterns like \`\(a\+\)\+b\` look innocent but explore an exponential number of partitions on a non-matching string \(\`aaaaaaaaaaaaaaaaaaaa\!\`\). The engine backtracks because many ways of splitting the \`a\`s among the inner and outer quantifiers match the same text. Real-world CVEs \(Cloudflare 2019, recent picomatch/addressable/MCP SDK ReDoS advisories\) come from exactly this. The fix is either remove the nesting or tell the engine not to backtrack. Linear-time engines avoid the problem entirely by refusing backreferences and lookaround.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-13T08:59:44.911494+00:00— report_created — created