Skip to main content

no-vulnerable

Disallow regular expressions that are potentially vulnerable to ReDoS (Regular Expression Denial of Service).

Targeted pattern scope​

This rule checks:

  • /(...)/flags literals.
  • RegExp("...") and new 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.

Rule catalog ID: R071

Further reading​