Interlace ESLint
ESLint Interlace
Secure CodingRules

no-redos-vulnerable-regex

ESLint Rule: no-redos-vulnerable-regex. This rule is part of [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding).

Keywords: no redos vulnerable regex, security, ESLint rule, JavaScript, TypeScript, CWE-400, CWE-1333, DoS, catastrophic backtracking

ESLint Rule: no-redos-vulnerable-regex. This rule is part of eslint-plugin-secure-coding.

Quick Summary

AspectDetails
SeverityError (Security)
Auto-Fix❌ No (requires manual review)
CategorySecurity
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForProduction applications handling user input
Suggestions✅ Advice on using atomic groups/safe libraries

Vulnerability and Risk

Vulnerability: Regular Expression Denial of Service (ReDoS) occurs when a regular expression is crafted in a way that causes catastrophic backtracking when processing certain input strings.

Risk: An attacker can provide a specially crafted input that triggers this catastrophic backtracking, causing the application to consume excessive CPU resources and become unresponsive (Denial of Service).

Error Message Format

The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:

🔒 CWE-400 OWASP:A06 CVSS:7.5 | Uncontrolled Resource Consumption (ReDoS) detected | HIGH
   Fix: Review and apply the recommended fix | https://owasp.org/Top10/A06_2021/

Message Components

ComponentPurposeExample
Risk StandardsSecurity benchmarksCWE-400 OWASP:A06 CVSS:7.5
Issue DescriptionSpecific vulnerabilityUncontrolled Resource Consumption (ReDoS) detected
Severity & ComplianceImpact assessmentHIGH
Fix InstructionActionable remediationFollow the remediation steps below
Technical TruthOfficial referenceOWASP Top 10

Rule Details

This rule detects regular expressions that are vulnerable to Regular Expression Denial of Service (ReDoS). ReDoS occurs when a regex engine takes an exponential amount of time to find a match (or fail to match) for certain inputs, usually due to "catastrophic backtracking".

Catastrophic backtracking happens when a regex contains:

  1. Nested Quantifiers: e.g., (a+)+
  2. Overlapping Disjunctions: e.g., (a|a)+
  3. Ambiguous Repetitions: e.g., (.*?)*

When these patterns are applied to a long string that almost matches but fails at the end, the regex engine tries every possible combination of repetitions, leading to $O(2^n)$ runtime.

Why This Matters

IssueImpactSolution
🔒 SecurityDenial of Service (DoS) attacksUse atomic groups or simple patterns
PerformanceServer freezing, high CPU usageValidate input length, use timeouts (if available)
🐛 ReliabilityUnexpected application crashesavoid nested quantifiers (a+)+

Configuration

This rule accepts an options object:

{
  "rules": {
    "secure-coding/no-redos-vulnerable-regex": ["error", {
      "allowCommonPatterns": false, // Default: false. Allow some common but potentially risky patterns if safe in context.
      "maxPatternLength": 500       // Default: 500. Maximum length of regex string to analyze.
    }]
  }
}

Examples

❌ Incorrect

// Nested quantifiers - O(2^n)
const badRegex1 = /(a+)+/;
const badRegex2 = /([a-zA-Z]+)*$/;

// Overlapping disjunctions
const badRegex3 = /(a|a)+/;

// Ambiguous optional repetitions
const badRegex4 = /(.*)*$/;

// Usage in RegExp constructor
const userPattern = new RegExp('(a+)+');

✅ Correct

// Non-nested quantifiers
const goodRegex1 = /a+/;
const goodRegex2 = /[a-zA-Z]+$/;

// Atomic groups (simulated in JS using lookahead)
// (?=(a+))\1 matches 'a+' atomically (no backtracking into it)
const atomicRegex = /(?=(a+))\1/;

// Using a safe library like validator.js for email/URL instead of custom regex
import isEmail from 'validator/lib/isEmail';
const valid = isEmail(input);

LLM-Based Suggestions

The rule provides guidance on how to fix detected patterns:

  • "Use Atomic Groups": Suggests simulating atomic groups or using re2.
  • "Restructure Regex": Recommends removing nesting or overlaps.
  • "Use Safe Library": Suggests using validator or zod for common patterns like emails.

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Values from Variables

Why: Values stored in variables are not traced.

// ❌ NOT DETECTED - Value from variable
const value = userInput;
dangerousOperation(value);

Mitigation: Validate all user inputs.

Wrapper Functions

Why: Custom wrappers not recognized.

// ❌ NOT DETECTED - Wrapper
myWrapper(userInput); // Uses dangerous API internally

Mitigation: Apply rule to wrapper implementations.

Dynamic Invocation

Why: Dynamic calls not analyzed.

// ❌ NOT DETECTED - Dynamic
obj[method](userInput);

Mitigation: Avoid dynamic method invocation.

Further Reading

On this page