# Regex Missing Timeout

#### Tools recognizing this:

<kbd>Fortify</kbd> <kbd>Checkmarx</kbd> <kbd>SonarQube</kbd> <kbd>Snyk</kbd> <kbd>Semgrep</kbd> <kbd>CodeQL</kbd>

## What is Regex Missing Timeout and How Does it Work?

Regex Missing Timeout is a security vulnerability that occurs when regular expressions are executed without a timeout limit. This can lead to denial of service attacks through catastrophic backtracking, where a malicious input causes the regex engine to spend excessive time processing.

The vulnerability can be exploited when:

* Complex regex patterns are used without timeout controls
* User input can influence the string being matched
* The regex pattern is susceptible to catastrophic backtracking
* No execution time limits are set for the regex operation

This guide covers Regex Missing Timeout vulnerabilities, examples, prevention methods, and how to implement proper timeout controls using real-world techniques.

## One Simple Regex Missing Timeout Attack Example

Consider this vulnerable regex implementation:

{% code overflow="wrap" %}

```
Regex regex = new Regex("^(a+)+b$");
bool isMatch = regex.IsMatch(userInput);
```

{% endcode %}

An attacker could provide this input:

<mark style="color:red;">`aaaaaaaaaaaaaaaaaaaaaaaaaaaaX`</mark>

This input would cause catastrophic backtracking, potentially freezing the application as the regex engine attempts to process all possible combinations.

## Regex Missing Timeout Prevention Methods: How to Fix Your Code

The most efficient way to fix a Regex Missing Timeout issue is by implementing proper timeout controls when executing regular expressions.

Adding timeouts ensures that regex operations cannot run indefinitely, protecting against denial of service attacks. Different programming languages offer various mechanisms to implement these controls.

### Code Samples

{% tabs %}
{% tab title="C#" %}
**Vulnerable Code**

```csharp
string pattern = @"^(a+)+b$";
string input = userInput;
Regex regex = new Regex(pattern);
bool isMatch = regex.IsMatch(input);
```

**Fixed Code**

```csharp
string pattern = @"^(a+)+b$";
string input = userInput;
Regex regex = new Regex(pattern, RegexOptions.None, TimeSpan.FromMilliseconds(30000));
bool isMatch = regex.IsMatch(input);
```

**Fix Explanation**

The vulnerable code creates a Regex without timeout controls.The fix adds a timeout parameter of 30 seconds using TimeSpan.FromMilliseconds.If the regex operation exceeds the timeout, it throws a RegexMatchTimeoutException.This prevents infinite processing of malicious inputs.
{% endtab %}

{% tab title="Java" %}
**Vulnerable Code**

```java
String pattern = "^(a+)+b$";
Pattern regex = Pattern.compile(pattern);
boolean isMatch = regex.matcher(userInput).matches();
```

**Fixed Code**

```java
String pattern = "^(a+)+b$";
Pattern regex = Pattern.compile(pattern);
RegexTimeout timeout = new RegexTimeout(30, TimeUnit.SECONDS);
boolean isMatch = timeout.matches(regex, userInput);

class RegexTimeout {
    private final long timeout;
    private final TimeUnit unit;
    
    public RegexTimeout(long timeout, TimeUnit unit) {
        this.timeout = timeout;
        this.unit = unit;
    }
    
    public boolean matches(Pattern pattern, String input) {
        FutureTask<Boolean> task = new FutureTask<>(() -> 
            pattern.matcher(input).matches());
        Thread thread = new Thread(task);
        thread.start();
        try {
            return task.get(timeout, unit);
        } catch (TimeoutException e) {
            thread.interrupt();
            throw new RuntimeException("Regex timeout exceeded");
        }
    }
}
```

**Fix Explanation**

The vulnerable code has no timeout mechanism for regex operations.The fix implements a custom timeout wrapper using FutureTask and Thread.The regex operation runs in a separate thread with a specified timeout.If the timeout is exceeded, the thread is interrupted and an exception is thrown.
{% endtab %}

{% tab title="Python" %}
**Vulnerable Code**

```python
import re

pattern = r'^(a+)+b$'
regex = re.compile(pattern)
is_match = bool(regex.match(user_input))
```

**Fixed Code**

```python
import re
import signal
from contextlib import contextmanager

@contextmanager
def timeout(seconds):
    def timeout_handler(signum, frame):
        raise TimeoutError("Regex timeout exceeded")
    
    original_handler = signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(seconds)
    try:
        yield
    finally:
        signal.alarm(0)
        signal.signal(signal.SIGALRM, original_handler)

pattern = r'^(a+)+b$'
regex = re.compile(pattern)
try:
    with timeout(30):
        is_match = bool(regex.match(user_input))
except TimeoutError:
    is_match = False
```

**Fix Explanation**

The vulnerable code has no timeout mechanism.The fix implements a context manager using signal.SIGALRM.Sets a 30-second timeout for the regex operation.If the timeout is exceeded, raises a TimeoutError.Note: This solution works only on Unix-like systems.
{% endtab %}

{% tab title="JavaScript" %}
**Vulnerable Code**

```javascript
const pattern = /^(a+)+b$/;
const isMatch = pattern.test(userInput);
```

**Fixed Code**

```javascript
function regexWithTimeout(pattern, input, timeout = 30000) {
    return new Promise((resolve, reject) => {
        const worker = new Worker(
            URL.createObjectURL(new Blob([`
                self.onmessage = function(e) {
                    const pattern = new RegExp(e.data.pattern);
                    const isMatch = pattern.test(e.data.input);
                    self.postMessage(isMatch);
                }
            `], { type: 'text/javascript' }))
        );

        const timeoutId = setTimeout(() => {
            worker.terminate();
            reject(new Error('Regex timeout exceeded'));
        }, timeout);

        worker.onmessage = (e) => {
            clearTimeout(timeoutId);
            worker.terminate();
            resolve(e.data);
        };

        worker.postMessage({ pattern: pattern.source, input });
    });
}

// Usage
const pattern = /^(a+)+b$/;
try {
    const isMatch = await regexWithTimeout(pattern, userInput);
} catch (error) {
    console.error('Regex timeout:', error);
}
```

**Fix Explanation**

The vulnerable code has no timeout controls.The fix uses a Web Worker to run regex in a separate thread.Implements a timeout using Promise and setTimeout.If the timeout is exceeded, the worker is terminated.This prevents the main thread from being blocked by long-running regex operations.
{% endtab %}

{% tab title="PHP" %}
**Vulnerable Code**

```php
$pattern = '/^(a+)+b$/';
$isMatch = preg_match($pattern, $userInput);
```

**Fixed Code**

```php
function regexWithTimeout($pattern, $input, $timeout = 30) {
    $previousLimit = ini_get('max_execution_time');
    set_time_limit($timeout);
    
    try {
        $startTime = microtime(true);
        $isMatch = preg_match($pattern, $input);
        
        if (microtime(true) - $startTime >= $timeout) {
            throw new Exception('Regex timeout exceeded');
        }
        
        return $isMatch;
    } finally {
        set_time_limit($previousLimit);
    }
}

try {
    $pattern = '/^(a+)+b$/';
    $isMatch = regexWithTimeout($pattern, $userInput);
} catch (Exception $e) {
    // Handle timeout exception
}
```

**Fix Explanation**

The vulnerable code has no timeout mechanism.The fix implements a wrapper function with timeout control.Uses set\_time\_limit() to enforce a maximum execution time.Monitors actual execution time using microtime().Restores original time limit after execution.
{% endtab %}
{% endtabs %}

## Need more help in preventing Regex Missing Timeout?

[Mobb](https://mobb.ai) supports fixing many forms of Regex Missing Timeout vulnerabilities, and can mitigate your issues in batch.

Start now for free at [app.mobb.ai](https://app.mobb.ai)

### We'd love your feedback!

We're excited to hear your thoughts and ideas about fixing vulnerabilities.

[Book a meeting](https://calendly.com/mobbai/demo) or [Contact us](https://content.mobb.ai/contact) if you have any corrections, questions or suggestions. Start now for free at <https://app.mobb.ai>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mobb.ai/mobb-user-docs/fixing-guides/regex-missing-timeout-fix-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
