no-vulnerable
Disallow regular expressions that are potentially vulnerable to ReDoS (Regular Expression Denial of Service).
Targeted pattern scope
This rule checks:
/(...)/flagsliterals.RegExp("...")andnew RegExp("...", "flags")when both arguments are statically-known strings.
This rule intentionally skips dynamic patterns/flags it cannot resolve safely at lint time.
What this rule reports
This rule analyzes regular expression literals and statically-resolvable RegExp(...) constructor calls using recheck.
This rule reports patterns that recheck identifies as vulnerable with polynomial or exponential complexity.
Why this rule exists
Catastrophic backtracking can make an application spend excessive CPU time on crafted inputs. In server contexts, that can become an availability issue.
❌ Incorrect
const unsafe = /(a+)+$/;
const unsafe = RegExp("(a+)+$");
const unsafe = new RegExp("(a+)+$", "u");
✅ Correct
const safe = /^a+$/;
const source = getPatternFromConfig();
const maybeUnsafe = RegExp(source); // Dynamic value: intentionally not analyzed.
Behavior and migration notes
type Options = [
{
ignoreErrors?: boolean;
permittableComplexities?: Array<"polynomial" | "exponential">;
timeout?: number | null;
}?,
];
Default options
{
ignoreErrors: true,
permittableComplexities: [],
}
ignoreErrors
When true (default), analysis failures from recheck are ignored.
When false, analysis failures are reported.
Analyzer failures include invalid regular expression syntax and backend startup
errors from the recheck runtime. On Windows, this rule normalizes the
temporary RECHECK_JAR and RECHECK_BIN values while invoking recheck so an
upstream path-separator bug cannot make Java execute package.json instead of
recheck.jar.
permittableComplexities
Allows selected vulnerable complexity classes to pass.
For example, to allow polynomial but still report exponential:
{
permittableComplexities: ["polynomial"],
}
Original plugin source: eslint-plugin-redos-detector.
ESLint flat config example
import etcMisc from "eslint-plugin-etc-misc";
export default [
{
plugins: { "etc-misc": etcMisc },
rules: {
"etc-misc/no-vulnerable": "error",
},
},
];
When not to use it
- If your codebase never handles untrusted input with regexes.
- If lint-time regex analysis cost is unacceptable for your workflow.
- If you prefer running ReDoS scanning as a separate CI security step rather than as an ESLint rule.