# Insecure Session Token Generation via random.Random() Predictability

Language: Python
Severity: Critical
CWE: CWE-338

## Source
10

## Flow
10-11-12

## Sink
12

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

app = Flask(__name__)
iot_device_sessions = {}

@app.route('/iot/provision', methods=['POST'])
def provision_device():
    device_id = request.json.get('device_id')
    seed_val = int(device_id.split('-')[1])
    rng = random.Random(seed_val)
    session_key = hashlib.sha256(str(rng.getrandbits(128)).encode()).hexdigest()
    iot_device_sessions[device_id] = session_key
    return jsonify({'device_id': device_id, 'session_key': session_key, 'status': 'provisioned'})
```

## Explanation

The application uses user-controlled device_id input to derive a seed for random.Random(), making the random number generation predictable. An attacker who knows or can predict the device_id pattern can reproduce the exact same session key, allowing unauthorized access to IoT devices.

## Remediation

The fix replaces the predictable random.Random() seeded with user-controlled input with secrets.token_hex(32), which uses the operating system's cryptographically secure random number generator (CSPRNG) to produce a 256-bit session key. This ensures the session key has full entropy and cannot be predicted or reproduced by an attacker regardless of knowledge of the device_id.

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

app = Flask(__name__)
iot_device_sessions = {}

@app.route('/iot/provision', methods=['POST'])
def provision_device():
    device_id = request.json.get('device_id')
    if not device_id or not isinstance(device_id, str):
        return jsonify({'error': 'Invalid device_id'}), 400
    session_key = secrets.token_hex(32)
    iot_device_sessions[device_id] = session_key
    return jsonify({'device_id': device_id, 'session_key': session_key, 'status': 'provisioned'})
```
