Interlace ESLint
ESLint Interlace
MongoDBRules

no-unsafe-regex-query

Detects user input in MongoDB `$regex` operators that could cause ReDoS (Regular Expression Denial of Service) or information disclosure.

Keywords: ReDoS, CWE-400, MongoDB, $regex, regular expression, denial of service

Detects user input in MongoDB $regex operators that could cause ReDoS (Regular Expression Denial of Service) or information disclosure.

⚠️ This rule errors by default in the recommended config.

Quick Summary

AspectDetails
CWE ReferenceCWE-400 (Resource Exhaustion)
OWASPA03:2021 - Injection
SeverityHigh (CVSS: 7.5)
CategorySecurity

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

User input in $regex operators is dangerous because:

  1. ReDoS attacks: Crafted regex patterns can cause exponential backtracking
  2. Information disclosure: Regex can be used to probe for data patterns
  3. Injection: Special regex characters can alter query behavior

Attack Example

// Attacker sends: "(a+)+$"
// This causes exponential backtracking on strings like "aaaaaaaaaa!"
db.users.find({ email: { $regex: userInput } });

❌ Incorrect

// User input directly in $regex
User.find({ name: { $regex: req.query.search } });

// User input as regex pattern
User.find({ email: { $regex: new RegExp(userInput) } });

// User input with $options
User.find({ name: { $regex: req.body.pattern, $options: 'i' } });

✅ Correct

// Escape special regex characters
import escapeRegex from 'escape-string-regexp';
User.find({ name: { $regex: escapeRegex(req.query.search), $options: 'i' } });

// Use $text search instead (indexed, safer)
User.find({ $text: { $search: req.query.search } });

// Anchor and limit pattern
const safePattern = `^${escapeRegex(req.query.search).slice(0, 50)}`;
User.find({ name: { $regex: safePattern } });

// Use MongoDB text index
db.users.createIndex({ name: 'text' });
User.find({ $text: { $search: userInput } });

Known False Negatives

Sanitized Input

// ❌ NOT DETECTED - but may still be vulnerable
const sanitized = userInput.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
User.find({ name: { $regex: sanitized } });

When Not To Use It

  • When using escape-string-regexp or similar libraries consistently
  • When regex patterns are from trusted source (internal config)

References

On this page