redos_prescan report — 5 file(s), 10 finding(s)

HIGH   REDOS-USER-PATTERN         hostile/search.js:2  regex built from request-derived input — pattern injection plus unknown complexity
       | const re = new RegExp(req.query.q);
HIGH   REDOS-NESTED-QUANT         hostile/search.js:3  quantified group wraps a quantified atom with an ambiguous iteration boundary — exponential backtracking in /^([a-zA-Z0-9_\-\.]+)+@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/
       | const EMAIL = /^([a-zA-Z0-9_\-\.]+)+@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/;
HIGH   REDOS-NESTED-QUANT         hostile/search.js:5  quantified group wraps a quantified atom with an ambiguous iteration boundary — exponential backtracking in /^(a+)+$/
       | function ok(s) { return /^(a+)+$/.test(s); }
HIGH   REDOS-NESTED-QUANT         hostile/tag.php:4  quantified group wraps a quantified atom with an ambiguous iteration boundary — exponential backtracking in /^(\d+)+$/
       | preg_match('/^(\d+)+$/', $id, $m);
HIGH   REDOS-NESTED-QUANT         hostile/validate.py:5  quantified group wraps a quantified atom with an ambiguous iteration boundary — exponential backtracking in /^(\w+)+$/
       | evil = re.compile(r'^(\w+)+$')
HIGH   REDOS-OVERLAP-ALT          hostile/validate.py:6  alternation branches in a repeating group can match the same text — exponential ambiguity in /^(a|aa)+$/
       | redos2 = re.compile(r'^(a|aa)+$')
HIGH   REDOS-USER-PATTERN         hostile/validate.py:9  regex built from request-derived input — pattern injection plus unknown complexity
       | p = re.compile(request.args['pat'])
MEDIUM REDOS-USER-PATTERN         hostile/tag.php:3  regex built from a non-literal — pattern injection plus unknown complexity
       | if (preg_match($pat, $body)) { hit(); }
MEDIUM REDOS-INPUT-APPLIED        hostile/validate.py:10  a flagged-dangerous pattern in this file is applied to request-derived input — the blowup is reachable
       | return evil.match(request.form['bio']), p.search(request.form['bio'])
LOW    REDOS-USER-PATTERN         clean/util.js:5  regex built from a non-literal — escape call present; verify it covers the whole interpolated piece
       | const dyn = new RegExp('^' + escapeRegExp(q) + '$');

scope: deterministic pre-scan — flags regex shapes that can be driven into catastrophic backtracking; not an audit, clean != ReDoS-safe
