# Timing Attack via Naive String Comparison in HMAC Verification

Language: Python
Severity: High
CWE: CWE-208

## Source
5

## Flow
5-6

## Sink
6

## Vulnerable Code
```python
import hmac
import hashlib

def validate_iot_device_signature(device_payload, received_sig, shared_secret):
    computed_sig = hmac.new(shared_secret.encode(), device_payload.encode(), hashlib.sha256).hexdigest()
    if computed_sig == received_sig:
        return {"authenticated": True, "device_id": device_payload.split(':')[0]}
    return {"authenticated": False, "device_id": None}

def process_telemetry_data(device_msg, signature, secret_key):
    auth_result = validate_iot_device_signature(device_msg, signature, secret_key)
    if auth_result["authenticated"]:
        telemetry = device_msg.split(':')[1]
        return {"status": "accepted", "data": telemetry}
    return {"status": "rejected", "error": "Invalid signature"}
```

## Explanation

The code uses naive string comparison (==) to validate HMAC signatures instead of constant-time comparison. This allows timing attacks where an attacker can measure response times to deduce the correct signature byte-by-byte, as the comparison fails faster when earlier bytes are incorrect.

## Remediation

The fix replaces the naive string comparison operator (==) with hmac.compare_digest(), which performs a constant-time comparison of the two strings. This prevents timing attacks because the function takes the same amount of time regardless of how many bytes match, making it impossible for an attacker to deduce the correct signature by measuring response times.

## Secure Code
```python
import hmac
import hashlib

def validate_iot_device_signature(device_payload, received_sig, shared_secret):
    computed_sig = hmac.new(shared_secret.encode(), device_payload.encode(), hashlib.sha256).hexdigest()
    if hmac.compare_digest(computed_sig, received_sig):
        return {"authenticated": True, "device_id": device_payload.split(':')[0]}
    return {"authenticated": False, "device_id": None}

def process_telemetry_data(device_msg, signature, secret_key):
    auth_result = validate_iot_device_signature(device_msg, signature, secret_key)
    if auth_result["authenticated"]:
        telemetry = device_msg.split(':')[1]
        return {"status": "accepted", "data": telemetry}
    return {"status": "rejected", "error": "Invalid signature"}
```
