{"title":"HMAC Length Extension Attack via Insecure MAC Construction","language":"Python","severity":"Critical","cwe":"CWE-347","source_lines":[6],"flow_lines":[6,7],"sink_lines":[7],"vulnerable_code":"import hashlib\nimport hmac\n\ndef validate_iot_device_command(device_id, command_payload, received_signature, shared_secret):\n    raw_message = f\"{device_id}|{command_payload}\"\n    computed_hash = hashlib.sha256(shared_secret.encode() + raw_message.encode()).hexdigest()\n    if computed_hash == received_signature:\n        return True\n    return False\n\ndef execute_device_action(device_id, action, params, sig, secret_key):\n    command_string = f\"{action}:{params}\"\n    if validate_iot_device_command(device_id, command_string, sig, secret_key):\n        if action == \"unlock_door\":\n            return {\"status\": \"success\", \"message\": f\"Door unlocked for device {device_id}\"}\n        elif action == \"disable_alarm\":\n            return {\"status\": \"success\", \"message\": f\"Alarm disabled for device {device_id}\"}\n        elif action == \"grant_access\":\n            return {\"status\": \"success\", \"message\": f\"Access granted: {params}\"}\n        else:\n            return {\"status\": \"executed\", \"action\": action}\n    return {\"status\": \"error\", \"message\": \"Invalid signature\"}","explanation":"The code uses insecure MAC construction by concatenating the secret with the message before hashing (SHA256(secret + message)) instead of using proper HMAC. This makes it vulnerable to hash length extension attacks where an attacker who knows a valid signature can append arbitrary data to the original message and compute a valid signature for the extended message without knowing the secret key.","remediation":"The fix replaces the insecure concatenation-based MAC construction (SHA256(secret + message)) with Python's standard hmac.new() using SHA-256, which is resistant to length extension attacks due to its nested hashing structure (HMAC = H((K⊕opad) || H((K⊕ipad) || message))). Additionally, the equality comparison was changed from == to hmac.compare_digest() to prevent timing side-channel attacks.","secure_code":"import hashlib\nimport hmac\n\ndef validate_iot_device_command(device_id, command_payload, received_signature, shared_secret):\n    raw_message = f\"{device_id}|{command_payload}\"\n    computed_mac = hmac.new(shared_secret.encode(), raw_message.encode(), hashlib.sha256).hexdigest()\n    if hmac.compare_digest(computed_mac, received_signature):\n        return True\n    return False\n\ndef execute_device_action(device_id, action, params, sig, secret_key):\n    command_string = f\"{action}:{params}\"\n    if validate_iot_device_command(device_id, command_string, sig, secret_key):\n        if action == \"unlock_door\":\n            return {\"status\": \"success\", \"message\": f\"Door unlocked for device {device_id}\"}\n        elif action == \"disable_alarm\":\n            return {\"status\": \"success\", \"message\": f\"Alarm disabled for device {device_id}\"}\n        elif action == \"grant_access\":\n            return {\"status\": \"success\", \"message\": f\"Access granted: {params}\"}\n        else:\n            return {\"status\": \"executed\", \"action\": action}\n    return {\"status\": \"error\", \"message\": \"Invalid signature\"}"}