Back to Articles

RXXR2: Finding the Regexes That Will Take Down Your Application

[ View on GitHub ]

RXXR2: Finding the Regexes That Will Take Down Your Application

Hook

A single malicious string can turn a 10-millisecond regex match into a 10-minute CPU freeze. In 2019, Cloudflare went down globally because of one vulnerable regex pattern in their WAF rules.

Context

Regular expressions are everywhere in modern applications—input validation, URL routing, log parsing, security rules. They're convenient, expressive, and dangerously easy to get wrong. The problem isn't syntax errors; those fail fast. The real threat is Regular Expression Denial of Service (ReDoS), where certain regex patterns exhibit exponential time complexity on carefully crafted input. An attacker who understands your validation regex can send a string that causes catastrophic backtracking, pegging your CPU at 100% for seconds or minutes.

Traditional approaches to finding ReDoS vulnerabilities rely on fuzzing or manual code review. Fuzzing generates random inputs hoping to trigger slow behavior, but it's probabilistic and time-consuming. Manual review requires deep regex expertise and doesn't scale. RXXR2 takes a different approach: it uses static analysis rooted in formal language theory to mathematically prove whether a regex can exhibit exponential behavior. Originally developed as academic research at the University of Birmingham, Superhuman forked and enhanced it to handle production regex analysis at scale, adding features needed for real-world JavaScript regex engines.

Technical Insight

RXXR2's core insight is that ReDoS vulnerabilities arise from a specific structural pattern: nested quantifiers combined with ambiguous subpatterns. Consider this seemingly innocent regex for matching repeated words: /(\w+\s+)*$/. The outer * and inner + create nested loops, and the \s+ creates ambiguity—when matching "foo bar baz ", the engine doesn't know whether spaces belong to \s+ or the end-of-string anchor. On backtracking, it explores exponentially many paths.

The tool works in three phases. First, it parses the regex into an abstract syntax tree, normalizing different regex syntaxes into a canonical form. Second, it performs abstract interpretation to identify Kleene closures (quantifiers like * and +) that can cause exponential behavior. This isn't pattern matching; it's building automata and analyzing their properties. Third, when it finds a vulnerable pattern, it constructs a concrete witness—a prefix, a pumpable substring that can be repeated to amplify the attack, and a suffix.

Here's how you'd use RXXR2 in a CI/CD pipeline to check regexes:

# Check a single regex
echo '/(\w+\s+)*$/' | rxxr2

# Output shows the vulnerability structure:
# Vulnerable regex detected
# Prefix: ""
# Pumpable: "a "
# Suffix: "!"
# Attack string: "a a a a a a a a a a !"

The attack string demonstrates the vulnerability: repeating "a " increases match time exponentially. With 10 repetitions, the regex might take milliseconds. With 25, it could take seconds. With 40, minutes.

For integration into existing tools, RXXR2 provides an HTTP API that accepts JSON:

# Start the server
rxxr2 --server --port 8080

# Check a regex via HTTP
curl -X POST http://localhost:8080/check \
  -H "Content-Type: application/json" \
  -d '{"regex": "/(\\w+\\s+)*$/"}'

# Response:
# {
#   "vulnerable": true,
#   "prefix": "",
#   "pump": "a ",
#   "suffix": "!",
#   "attack": "a a a a a a a a a a !"
# }

This makes it trivial to build RXXR2 checks into linters, pre-commit hooks, or security scanners. You could validate all regexes in your codebase during PR reviews, flagging any that exhibit exponential behavior before they reach production.

The formal methods approach means RXXR2 doesn't need to run the regex—it analyzes the structure mathematically. This is both faster and more complete than fuzzing. If RXXR2 says a regex is vulnerable, it's providing a mathematical proof, not a probabilistic guess. The witness string it generates isn't just one example; it's a template showing exactly how to exploit the vulnerability.

Superhuman's fork added critical features for production use: better handling of JavaScript regex features like lookaheads and Unicode properties, batch processing for analyzing thousands of regexes from rule files (like Snort IDS rules), and improved error messages that explain why a pattern is vulnerable in terms developers understand, not academic formal language theory.

Gotcha

RXXR2's static analysis is powerful but comes with the inherent limitations of all static analysis tools. It analyzes the regex pattern itself, not how it's used in context. If your application dynamically constructs regexes by concatenating strings based on user input or configuration, RXXR2 can't help—it needs the complete pattern at analysis time. This is a fundamental limitation: the tool can't predict what regexes your code might generate at runtime.

More importantly, RXXR2 doesn't yet support every regex feature in modern JavaScript engines. Unicode property escapes, named capture groups, and certain advanced lookahead/lookbehind patterns may not be fully analyzed. The repository documentation explicitly notes missing features and invites community contributions. If you're using cutting-edge regex features introduced in ES2018 or later, you'll need to verify RXXR2's coverage first. The tool may also produce false positives on complex patterns where the formal analysis is conservative—it might flag a regex as potentially vulnerable when practical input constraints would never trigger the exponential behavior. The OCaml implementation means contributing improvements requires functional programming knowledge, which narrows the potential contributor base compared to JavaScript or Python alternatives.

Verdict

Use if: You're building security-critical applications where user input touches regex validation, you need automated ReDoS checking in CI/CD pipelines, or you're auditing legacy codebases with hundreds of regexes scattered across your codebase. The HTTP API makes integration straightforward, and the formal methods approach gives you mathematical confidence rather than statistical guesses. It's particularly valuable for teams that can't afford to learn regex anti-patterns deeply—RXXR2 encodes that expertise. Skip if: You're working with very modern JavaScript regex features that aren't fully supported yet, your regexes are simple and obviously safe (literal strings, basic character classes without nested quantifiers), or you need to analyze dynamically constructed patterns. For teams without OCaml experience who need to extend the tool, JavaScript alternatives like safe-regex may be more approachable, though they offer less rigorous analysis. Think of RXXR2 as a specialized security tool, not a general regex linter—use it when ReDoS is a real threat, not just for catching typos.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/superhuman-rxxr2.svg)](https://starlog.is/api/badge-click/developer-tools/superhuman-rxxr2)