{
  "id": 17557793,
  "title": "Regular Expression Denial of Service (ReDoS) in JS & PHP: Spotting Catastrophic Backtracking",
  "url": "https://urgent.news/2026/11/01/regular-expression-denial-of-service-redos-in-js-php-spotting",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-11-01T07:44:36.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/muhammadalimughal/regular-expression-denial-of-service-redos-in-js-php-spotting-catastrophic-backtracking-3bfd"
  },
  "original_language": "en",
  "account": "ReDoS is a type of denial-of-service attack that exploits vulnerabilities in regular expression engines. In JavaScript and PHP, it occurs when a regex engine, such as V8's Irregexp in Node.js or PCRE2 in PHP's preg_* functions, goes into catastrophic backtracking while trying to match an input string. This happens when the pattern contains ambiguous quantifiers, leading to exponential or polynomial growth in the number of possible matches.\n\nTo spot catastrophic backtracking, look for nested or overlapping quantifiers in your regex patterns. For example, the pattern /^([a-z0-9]+-?)+$/ can be split into various combinations, resulting in a large number of potential matches. You can prove backtracking by crafting near-miss inputs and timing the execution of the regex test() call. The time taken will grow exponentially with the length of the input string if the engine is backtracking catastrophically.\n\nFive pattern smells to watch out for are:\n1. Nested quantifiers: Patterns with both inner and outer + quantifiers, like /^([a-z0-9]+-?)+$/\n2. Overlapping alternation: Alternating character classes within a repeated group, like /A/B+/A+/\n3. Polynomial exponential growth: Patterns with competing quantifiers for the same characters, like /^\\w+\\w*@/ or /\\d+\\.?\\d*/\n4. Adjacent overlapping repeats: Patterns with two quantifiers that can compete for the same characters, like /^\\w+\\w*/\n5. Quadratic tail: Unanchored greedy quantifiers at the end of the pattern, like /\\s+$/\n\nTo fix ReDoS vulnerabilities, rewrite your regex patterns to be unambiguous, ensuring that each character can only be consumed in one way. For example, the vulnerable slug pattern /^( [a-z0-9] +-?)+$/ can be rewritten as /^(?=[a-z0-9]*$)[a-z0-9]+(-[a-z0-9]+)*$/ to make it safe from catastrophic backtracking. Additionally, consider using tools like ESLint's regexp/no-super-linear-backtracking rule and recheck to automatically detect potential ReDoS issues in your code.",
  "summary": "Here is a pattern I keep finding in slug and username validators: /^([a-z0-9]+-?)+$/ . It looks harmless and passes every unit test. Now send it thirty lowercase letters followed by an underscore. On Node 24, that single test() call ran for about 6.5 seconds on my machine. Node runs your JavaScript on one event-loop thread, so every other request on that process waits for it. A handful of those…",
  "key_points": [
    "ReDoS exploits vulnerabilities in regex engines, causing catastrophic backtracking.",
    "Spot backtracking by identifying nested or overlapping quantifiers in patterns.",
    "Fix vulnerabilities by rewriting patterns to be unambiguous and avoid super-linear backtracking."
  ],
  "editors_take": "Identifying ambiguous quantifiers and overlapping patterns allows developers to prevent catastrophic backtracking from turning routine regular expression matches into resource-draining denial-of-service vulnerabilities.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}