# Regex DoS via Catastrophic Backtracking in re.search()

Language: Python
Severity: High
CWE: CWE-1333

## Source
8

## Flow
8-10

## Sink
10

## Vulnerable Code
```python
import re
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/api/iot/device/validate', methods=['POST'])
def validate_device_identifier():
    device_id = request.json.get('device_identifier', '')
    pattern = r'^(([a-zA-Z0-9]+)+)+@iot\.local$'
    if re.search(pattern, device_id):
        return jsonify({'status': 'valid', 'device': device_id})
    return jsonify({'status': 'invalid'}), 400
```

## Explanation

The regex pattern contains nested quantifiers (([a-zA-Z0-9]+)+)+ that cause catastrophic backtracking when processing malicious input. When re.search() attempts to match a string with many repeating characters followed by a non-matching character, the regex engine explores an exponential number of backtracking paths, leading to ReDoS (Regular Expression Denial of Service).

## Remediation

The fix replaces the vulnerable nested quantifier pattern (([a-zA-Z0-9]+)+)+ with a simple non-nested quantifier [a-zA-Z0-9]+ which matches the same valid inputs (one or more alphanumeric characters before @iot.local) without any backtracking risk. Additionally, an input length check is added as a defense-in-depth measure to prevent processing excessively long strings.

## Secure Code
```python
import re
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/api/iot/device/validate', methods=['POST'])
def validate_device_identifier():
    device_id = request.json.get('device_identifier', '')
    if len(device_id) > 255:
        return jsonify({'status': 'invalid'}), 400
    pattern = r'^[a-zA-Z0-9]+@iot\.local$'
    if re.search(pattern, device_id):
        return jsonify({'status': 'valid', 'device': device_id})
    return jsonify({'status': 'invalid'}), 400
```
