no-vulnerable
Disallow regular expressions that are potentially vulnerable to ReDoS (Regular Expression Denial of Service).
Why this rule is included here
This rule was integrated into eslint-plugin-etc-misc to avoid requiring a separate single-rule plugin dependency.
Original plugin source: eslint-plugin-redos-detector.
Rule details
This rule analyzes regular expression literals and statically-resolvable RegExp(...) constructor calls using recheck.
Catastrophic backtracking can make an application spend excessive CPU time on crafted inputs. In server contexts, that can become an availability issue.
This rule reports patterns that recheck identifies as vulnerable with polynomial or exponential complexity.
What this rule checks
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.
❌ 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.
Options
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"],
}
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.
Further reading
ESLint flat config example
import etcMisc from "eslint-plugin-etc-misc";
export default [
{
plugins: { "etc-misc": etcMisc },
rules: {
"etc-misc/no-vulnerable": "error",
},
},
];