# Timing Attack via Naive String Comparison in Authentication Tokens

Language: Python
Severity: High
CWE: CWE-208

## Source
6

## Flow
6-7

## Sink
7

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

def verify_iot_device_signature(device_id):
    stored_sig = get_device_signature_from_hsm(device_id)
    incoming_sig = request.headers.get('X-Device-Signature')
    if incoming_sig == stored_sig:
        return jsonify({'status': 'authorized', 'device': device_id})
    return jsonify({'status': 'unauthorized'}), 401

def get_device_signature_from_hsm(dev_id):
    return hashlib.sha256(f'device_{dev_id}_secret_key'.encode()).hexdigest()
```

## Explanation

The code uses naive string comparison (==) to verify cryptographic signatures, which performs character-by-character comparison and returns False as soon as a mismatch is found. This creates measurable timing differences that attackers can exploit to reconstruct valid signatures byte-by-byte through statistical analysis of response times.

## Remediation

The fix replaces the naive string comparison operator (==) with hmac.compare_digest(), which performs constant-time comparison regardless of where characters differ. This eliminates timing side-channel information that attackers could use to reconstruct valid device signatures byte-by-byte. An additional None check is added to handle missing headers gracefully before the comparison.

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

def verify_iot_device_signature(device_id):
    stored_sig = get_device_signature_from_hsm(device_id)
    incoming_sig = request.headers.get('X-Device-Signature')
    if incoming_sig is None:
        return jsonify({'status': 'unauthorized'}), 401
    if hmac.compare_digest(incoming_sig, stored_sig):
        return jsonify({'status': 'authorized', 'device': device_id})
    return jsonify({'status': 'unauthorized'}), 401

def get_device_signature_from_hsm(dev_id):
    return hashlib.sha256(f'device_{dev_id}_secret_key'.encode()).hexdigest()
```
