{"title":"Cryptographic Timing Attack via Non-Constant-Time HMAC Comparison","language":"Python","severity":"High","cwe":"CWE-208","source_lines":[6],"flow_lines":[6,7,8,9],"sink_lines":[9],"vulnerable_code":"import hmac\nimport hashlib\nfrom flask import request, jsonify\ndef verify_iot_device_token(dev_id):\n    raw_secret = b'iot_master_key_2024'\n    inbound_sig = request.headers.get('X-Device-Sig', '')\n    payload = f'{dev_id}:{request.remote_addr}'.encode()\n    expected_mac = hmac.new(raw_secret, payload, hashlib.sha256).hexdigest()\n    if inbound_sig == expected_mac:\n        return jsonify({'status': 'authorized', 'device': dev_id})\n    return jsonify({'status': 'denied'}), 403","explanation":"The untrusted HMAC signature is retrieved from the HTTP header at line 6 and compared to the expected MAC at line 9 using Python's native == operator. This performs a non-constant-time string comparison that short-circuits on the first mismatched byte, leaking timing information that allows an attacker to progressively reconstruct the valid HMAC value through statistical latency measurements.","remediation":"The fix replaces the vulnerable == operator on line 9 with hmac.compare_digest(), which performs a constant-time comparison of the two strings. This ensures that the comparison always takes the same amount of time regardless of how many bytes match, completely eliminating the timing side-channel that would allow an attacker to progressively reconstruct the valid HMAC signature.","secure_code":"import hmac\nimport hashlib\nfrom flask import request, jsonify\ndef verify_iot_device_token(dev_id):\n    raw_secret = b'iot_master_key_2024'\n    inbound_sig = request.headers.get('X-Device-Sig', '')\n    payload = f'{dev_id}:{request.remote_addr}'.encode()\n    expected_mac = hmac.new(raw_secret, payload, hashlib.sha256).hexdigest()\n    if hmac.compare_digest(inbound_sig, expected_mac):\n        return jsonify({'status': 'authorized', 'device': dev_id})\n    return jsonify({'status': 'denied'}), 403"}