# Timing Attack via Non-Constant-Time HMAC Comparison

Language: Python
Severity: High
CWE: CWE-208

## Source
6

## Flow
6-7

## Sink
7

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

def verify_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(dev_id):
    device_secrets = {"sensor_001": "a8f3c9e2b7d1", "actuator_042": "9d2e1f4a6b8c"}
    return device_secrets.get(dev_id, "default_key")
```

## Explanation

The code uses Python's standard string equality operator (==) to compare HMAC signatures, which performs character-by-character comparison and exits early on the first mismatch. This timing difference allows attackers to perform timing attacks to gradually deduce the correct signature by measuring response times for each byte position.

## Remediation

The fix replaces the vulnerable string equality operator (==) with hmac.compare_digest(), which performs a constant-time comparison of the two strings. This ensures that the comparison takes the same amount of time regardless of how many characters match, preventing timing-based side-channel attacks that could allow an attacker to deduce the correct signature byte by byte.

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

def verify_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(dev_id):
    device_secrets = {"sensor_001": "a8f3c9e2b7d1", "actuator_042": "9d2e1f4a6b8c"}
    return device_secrets.get(dev_id, "default_key")
```
