# Timing Attack via naive HMAC comparison

Language: Python
Severity: High
CWE: CWE-208

## Source
6

## Flow
6-7

## Sink
7

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

def validate_iot_device_signature(device_id, payload, received_sig):
    secret_key = get_device_secret(device_id)
    expected_sig = hmac.new(secret_key.encode(), payload.encode(), hashlib.sha256).hexdigest()
    if received_sig == expected_sig:
        return {"authenticated": True, "device": device_id}
    return {"authenticated": False}

def get_device_secret(device_id):
    device_secrets = {"thermostat_01": "k8j2n4m9p1q5", "camera_02": "x7v3b6n2m8k4"}
    return device_secrets.get(device_id, "default_secret")
```

## Explanation

The code uses a naive string equality comparison (==) to validate HMAC signatures instead of a constant-time comparison function. This allows timing attacks where an attacker can measure response times to determine correct signature bytes one at a time, eventually reconstructing a valid signature without knowing the secret key.

## Remediation

The fix replaces the naive string equality comparison (==) with hmac.compare_digest(), which is a constant-time comparison function provided by Python's hmac module. This function takes the same amount of time regardless of how many bytes match, preventing an attacker from using timing measurements to progressively guess the correct signature byte by byte.

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

def validate_iot_device_signature(device_id, payload, received_sig):
    secret_key = get_device_secret(device_id)
    expected_sig = hmac.new(secret_key.encode(), payload.encode(), hashlib.sha256).hexdigest()
    if hmac.compare_digest(received_sig, expected_sig):
        return {"authenticated": True, "device": device_id}
    return {"authenticated": False}

def get_device_secret(device_id):
    device_secrets = {"thermostat_01": "k8j2n4m9p1q5", "camera_02": "x7v3b6n2m8k4"}
    return device_secrets.get(device_id, "default_secret")
```
