# Timing Attack via Naive Equality Comparison for API Key Verification

Language: Python
Severity: High
CWE: CWE-208

## Source
9

## Flow
9-10-11

## Sink
11

## Vulnerable Code
```python
import hashlib
from flask import Flask, request, jsonify

app = Flask(__name__)
IOT_DEVICE_MASTER_KEY = "iot_secure_key_9a8f7e6d5c4b3a2"

@app.route('/api/v1/device/telemetry', methods=['POST'])
def receive_telemetry():
    device_auth_header = request.headers.get('X-Device-Auth-Token', '')
    computed_hash = hashlib.sha256(device_auth_header.encode()).hexdigest()
    expected_hash = hashlib.sha256(IOT_DEVICE_MASTER_KEY.encode()).hexdigest()
    if computed_hash == expected_hash:
        telemetry_data = request.json
        return jsonify({"status": "accepted", "device_id": telemetry_data.get('device_id')}), 200
    return jsonify({"error": "unauthorized_device"}), 401
```

## Explanation

The code uses Python's standard equality operator (==) to compare hashed authentication tokens, which is vulnerable to timing attacks. The comparison short-circuits on the first mismatching character, allowing attackers to measure response times and iteratively guess the correct hash byte-by-byte, even though SHA-256 is used.

## Remediation

The fix replaces the naive equality operator (==) with hmac.compare_digest(), which performs a constant-time comparison of the two hash strings. This prevents timing attacks because the function always takes the same amount of time regardless of how many characters match, eliminating the information leakage from early short-circuit exits.

## Secure Code
```python
import hashlib
import hmac
from flask import Flask, request, jsonify

app = Flask(__name__)
IOT_DEVICE_MASTER_KEY = "iot_secure_key_9a8f7e6d5c4b3a2"

@app.route('/api/v1/device/telemetry', methods=['POST'])
def receive_telemetry():
    device_auth_header = request.headers.get('X-Device-Auth-Token', '')
    computed_hash = hashlib.sha256(device_auth_header.encode()).hexdigest()
    expected_hash = hashlib.sha256(IOT_DEVICE_MASTER_KEY.encode()).hexdigest()
    if hmac.compare_digest(computed_hash, expected_hash):
        telemetry_data = request.json
        return jsonify({"status": "accepted", "device_id": telemetry_data.get('device_id')}), 200
    return jsonify({"error": "unauthorized_device"}), 401
```
