{"title":"Regex Denial of Service via Catastrophic Backtracking","language":"Python","severity":"High","cwe":"CWE-1333","source_lines":[9],"flow_lines":[9,10,4,5],"sink_lines":[5],"vulnerable_code":"import re\nfrom flask import request, jsonify\n\ndef validate_iot_device_identifier(device_id):\n    pattern = r'^(([a-zA-Z0-9]+)*-)*([a-zA-Z0-9]+)+$'\n    if re.match(pattern, device_id):\n        return jsonify({'status': 'valid', 'device': device_id})\n    return jsonify({'status': 'invalid'})\n\n@app.route('/api/iot/register', methods=['POST'])\ndef register_sensor():\n    sensor_id = request.json.get('sensor_identifier', '')\n    return validate_iot_device_identifier(sensor_id)","explanation":"The regex pattern contains nested quantifiers (([a-zA-Z0-9]+)*-)* which causes catastrophic backtracking when matching fails. When an attacker submits a long string of alphanumeric characters followed by a hyphen, the regex engine explores exponentially many matching possibilities, leading to CPU exhaustion and denial of service.","remediation":"The fix replaces the vulnerable regex pattern `^(([a-zA-Z0-9]+)*-)*([a-zA-Z0-9]+)+$` which had nested quantifiers causing catastrophic backtracking, with a safe equivalent `^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$` that matches the same valid inputs (hyphen-separated alphanumeric segments) without any nested quantifiers. Additionally, an input length check is added as a defense-in-depth measure to cap processing time even if future regex changes introduce issues.","secure_code":"import re\nfrom flask import request, jsonify\n\ndef validate_iot_device_identifier(device_id):\n    # Limit input length to prevent abuse\n    if not device_id or len(device_id) > 256:\n        return jsonify({'status': 'invalid'})\n    # Use a non-backtracking regex pattern that matches hyphenated alphanumeric identifiers\n    pattern = r'^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$'\n    if re.match(pattern, device_id):\n        return jsonify({'status': 'valid', 'device': device_id})\n    return jsonify({'status': 'invalid'})\n\n@app.route('/api/iot/register', methods=['POST'])\ndef register_sensor():\n    sensor_id = request.json.get('sensor_identifier', '')\n    return validate_iot_device_identifier(sensor_id)"}