REGEX REDOS CHECK · RUNS IN YOUR BROWSER

Which regexes in your code can hang your server?

Paste source code and get every regular expression that can backtrack catastrophically — nested repeats like (a+)+, overlapping alternation like (a|aa)+, adjacent repeats over the same characters, and trailing \s+$ trims with no start anchor. One crafted string can pin a CPU core; this finds the pattern before someone sends the string.

Nothing is uploaded and your patterns are never executed here: the page only parses the text. A finding is a suspect, not a proof — the CLI's --probe mode confirms one by timing the real JavaScript engine.

1. Paste your code

Prefer a CLI, or want this as a CI gate?

Same engine, zero dependencies — walks a whole source tree, skipping node_modules, .git and similar:

node cli.mjs scan src                      # human-readable
node cli.mjs scan . --json                    # machine-readable
node cli.mjs scan src --probe                 # time the real JS engine to confirm suspects
node cli.mjs scan src --fail-on warn          # fail CI on polynomial warnings too
node cli.mjs check '(a+)+$'                   # analyse one pattern

Get cli.mjs, engine.mjs and probe.mjs — Node 18+, nothing to install, no network call. Exits 1 on a likely-exponential pattern (or on any warning with --fail-on warn). More: how ReDoS works and how to find it before an attacker does.

What's recognised

LanguageWhere regexes are read from

Rules: nested-quantifier, overlapping-alternation (exponential, errors); adjacent-overlap, quadratic-end-anchor (polynomial, warnings); dynamic-regexp (note). Patterns built by string concatenation are not guessed at. Linear-time engines (RE2, Go, Rust) are not affected by any of this.

Common questions

Does this run my regexes or upload my code?

The browser page only parses the text you paste, in your own browser, and never sends it anywhere. It does not execute your patterns. The CLI reads local files and makes no network call; its optional --probe mode runs a pattern against generated strings in a sandboxed Node vm with a hard timeout.

What does a finding actually mean?

It is a suspect, not a proof. The analysis reads the structure of the pattern and finds shapes where a backtracking engine can match the same text in many ways, so a long input that almost matches takes exponential or polynomial time. Whether that is exploitable depends on whether an attacker controls the input and how long it can be. The CLI's --probe mode times the real JavaScript engine on a generated input to confirm.

Which regex engines does this apply to?

Backtracking engines: JavaScript, Python's re, Java, .NET, Ruby (before 3.2's memoisation), PHP's PCRE. Engines built on automata, such as RE2, Go's regexp and Rust's regex crate, run in linear time and are not affected. Patterns are parsed with JavaScript semantics, with Python named groups, inline flags and possessive quantifiers accepted.

Why does it flag \s+$ with no ^?

Without a start anchor the engine retries the pattern from every position. On a string with a long run of spaces that is not at the end, each retry scans the whole run again, which is quadratic. A trim like that was behind a 2016 Stack Overflow outage. Anchor the start, or use String.prototype.trim().