{"title":"HMAC Verification Timing Attack via `==` String Comparison","language":"Python","severity":"High","cwe":"CWE-208","source_lines":[7],"flow_lines":[7,8],"sink_lines":[8],"vulnerable_code":"import hmac\nimport hashlib\nfrom flask import request, jsonify\n\ndef verify_iot_device_command(device_id, command_payload, signature_header):\n    device_secret = get_device_secret_key(device_id)\n    expected_sig = hmac.new(device_secret.encode(), command_payload.encode(), hashlib.sha256).hexdigest()\n    if signature_header == expected_sig:\n        execute_device_command(device_id, command_payload)\n        return jsonify({\"status\": \"executed\", \"device\": device_id})\n    return jsonify({\"error\": \"invalid signature\"}), 403\n\ndef get_device_secret_key(dev_id):\n    return f\"iot_secret_{dev_id}_key\"\n\ndef execute_device_command(dev_id, cmd):\n    pass","explanation":"The code uses a direct string comparison (`==`) to verify HMAC signatures instead of a constant-time comparison function. This allows attackers to perform timing attacks by measuring response times to determine each correct byte of the signature sequentially, eventually forging valid signatures to execute arbitrary device commands.","remediation":"The fix replaces the vulnerable `==` string comparison with `hmac.compare_digest()`, which performs a constant-time comparison that takes the same amount of time regardless of how many bytes match. This prevents attackers from using timing side-channels to incrementally determine the correct signature byte-by-byte.","secure_code":"import hmac\nimport hashlib\nfrom flask import request, jsonify\n\ndef verify_iot_device_command(device_id, command_payload, signature_header):\n    device_secret = get_device_secret_key(device_id)\n    expected_sig = hmac.new(device_secret.encode(), command_payload.encode(), hashlib.sha256).hexdigest()\n    if hmac.compare_digest(signature_header, expected_sig):\n        execute_device_command(device_id, command_payload)\n        return jsonify({\"status\": \"executed\", \"device\": device_id})\n    return jsonify({\"error\": \"invalid signature\"}), 403\n\ndef get_device_secret_key(dev_id):\n    return f\"iot_secret_{dev_id}_key\"\n\ndef execute_device_command(dev_id, cmd):\n    pass"}