{"title":"Regex Denial of Service via Catastrophic Backtracking","language":"Python","severity":"High","cwe":"CWE-1333","source_lines":[9],"flow_lines":[9,11],"sink_lines":[11],"vulnerable_code":"import re\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n@app.route('/api/iot/validate_sensor_data', methods=['POST'])\ndef validate_sensor_telemetry():\n    telemetry_payload = request.json.get('sensor_output', '')\n    pattern = r'^(([a-zA-Z0-9]+)+)+@device\\.(local|cloud)$'\n    if re.match(pattern, telemetry_payload):\n        return jsonify({'status': 'valid', 'processed': True})\n    return jsonify({'status': 'invalid', 'processed': False}), 400","explanation":"The regex pattern contains nested quantifiers (([a-zA-Z0-9]+)+)+ which causes catastrophic backtracking. When untrusted input from request.json is passed to re.match(), a specially crafted input with repetitive characters followed by a non-matching suffix forces exponential time complexity, enabling ReDoS attacks that can hang the server.","remediation":"The fix removes the nested quantifiers (([a-zA-Z0-9]+)+)+ which caused catastrophic backtracking, replacing them with a single [a-zA-Z0-9]+ character class that matches one or more alphanumeric characters without any nesting. An input length check is also added as a defense-in-depth measure to prevent excessively long inputs from being processed.","secure_code":"import re\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n@app.route('/api/iot/validate_sensor_data', methods=['POST'])\ndef validate_sensor_telemetry():\n    telemetry_payload = request.json.get('sensor_output', '')\n    if len(telemetry_payload) > 256:\n        return jsonify({'status': 'invalid', 'processed': False}), 400\n    pattern = r'^[a-zA-Z0-9]+@device\\.(local|cloud)$'\n    if re.match(pattern, telemetry_payload):\n        return jsonify({'status': 'valid', 'processed': True})\n    return jsonify({'status': 'invalid', 'processed': False}), 400"}