ReDoS checker
Can this regex hang?
Find the nested and overlapping repetitions that cause catastrophic backtracking, then measure them with attack strings in a worker that is stopped before it can freeze anything.
Valid pattern · 1 capture group · 3 quantifiers · no flags
Exponential backtracking risk
At least one part of this pattern can make a backtracking engine, like the one in every browser and in Node.js, take exponentially longer as the input grows. A short malicious string can hang a page or a server.
HighNested quantifier: exponential backtracking
(\w+\s?)* repeats \w+, which can itself match one or more characters, so a run of "a" can be split between iterations in many ways. When the rest of the pattern then fails, the engine tries every way of dividing the text, and the work roughly doubles with each extra character.
Attack string: "a" × n + "!"
Time your own input
How the check works, and its limits
Browsers and Node.js match regexes by backtracking: when part of a pattern fails, the engine goes back and tries another way. If a pattern can match the same text in many ways, for example (a+)+, where a run of a’s can be divided between the inner and outer repetition in exponentially many ways, a failing match tries them all.
The checker parses the pattern and looks for three shapes: nested quantifiers whose repetitions can share characters, alternatives under a repetition that can match the same text, and adjacent unbounded quantifiers that overlap (quadratic). It also notes unanchored patterns that start with a repetition. For each finding it builds an attack string, a prefix, a repeated “pump” and a suffix that makes the match fail, which you can time in a worker; any run longer than 2.5 seconds is stopped.
These are heuristics, not a proof. They can miss problems (especially with backreferences and lookarounds) and can flag patterns your engine happens to optimise. A timed test only shows what this browser does with the generated input. The robust fixes are to make each character matchable in only one way, to bound repetitions and input length, or to use a linear-time engine such as RE2.
Questions
Is a “no risky constructs” result a guarantee?
No. It means none of the known dangerous shapes were found. Test with long inputs that almost match, and limit input length wherever untrusted text meets a regex.
Can the timed test freeze my browser?
No. Each run happens in a Web Worker, which is terminated if it has not finished after 2.5 seconds. The page itself stays responsive.
How do I fix a flagged pattern?
Remove the ambiguity: (\w+\s?)* becomes \w+(?:\s\w+)*, and (a|aa)+ becomes a+. Make separators mandatory, avoid nesting repetitions of the same characters and cap lengths with {1,64} where you can.