{"title":"Regex DoS via Catastrophic Backtracking","language":"Python","severity":"High","cwe":"CWE-1333","source_lines":[12],"flow_lines":[12,13,4,5],"sink_lines":[5],"vulnerable_code":"import re\nfrom flask import request, jsonify\n\ndef validate_iot_device_firmware_version(firmware_string):\n    version_pattern = r'^(v?\\d+\\.)*\\d+(-[a-zA-Z0-9]+)*$'\n    if re.match(version_pattern, firmware_string):\n        return jsonify({\"status\": \"valid\", \"version\": firmware_string})\n    return jsonify({\"status\": \"invalid\"}), 400\n\n@app.route('/api/iot/firmware/validate', methods=['POST'])\ndef check_firmware_compatibility():\n    device_firmware = request.json.get('firmware_version', '')\n    return validate_iot_device_firmware_version(device_firmware)","explanation":"The regex pattern r'^(v?\\d+\\.)*\\d+(-[a-zA-Z0-9]+)*$' contains nested quantifiers that cause catastrophic backtracking. When malicious input with many repeating groups is provided, the regex engine exponentially backtracks trying all possible match combinations, causing CPU exhaustion and denial of service.","remediation":"The fix applies two key mitigations: First, it enforces a strict maximum input length (128 characters) which prevents the regex engine from having enough input to cause meaningful CPU exhaustion through backtracking. Second, the regex groups use non-capturing syntax (?:...) which, combined with the input length restriction, makes catastrophic backtracking infeasible even on adversarial inputs. The length limit is the primary defense since firmware version strings should never be longer than a reasonable bound.","secure_code":"import re\nfrom flask import request, jsonify\n\nMAX_FIRMWARE_LENGTH = 128\n\ndef validate_iot_device_firmware_version(firmware_string):\n    if not firmware_string or len(firmware_string) > MAX_FIRMWARE_LENGTH:\n        return jsonify({\"status\": \"invalid\", \"error\": \"Invalid firmware string length\"}), 400\n\n    version_pattern = r'^v?(?:\\d+\\.)*\\d+(?:-[a-zA-Z0-9]+)*$'\n\n    if re.match(version_pattern, firmware_string):\n        return jsonify({\"status\": \"valid\", \"version\": firmware_string})\n    return jsonify({\"status\": \"invalid\"}), 400\n\n@app.route('/api/iot/firmware/validate', methods=['POST'])\ndef check_firmware_compatibility():\n    device_firmware = request.json.get('firmware_version', '')\n    return validate_iot_device_firmware_version(device_firmware)"}