# Insecure Randomness in Token Generation via `random` Module

Language: Python
Severity: Critical
CWE: CWE-338

## Source
10

## Flow
10

## Sink
10

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

app = Flask(__name__)
iot_device_sessions = {}

@app.route('/api/iot/provision', methods=['POST'])
def provision_device():
    device_id = request.json.get('device_id')
    device_key = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(48))
    iot_device_sessions[device_id] = {'key': device_key, 'status': 'active'}
    return jsonify({'device_id': device_id, 'provisioning_key': device_key, 'expires': 86400})
```

## Explanation

The code uses Python's `random` module to generate cryptographic keys for IoT device authentication. The `random` module uses a Mersenne Twister PRNG which is predictable and not cryptographically secure, allowing attackers to predict future keys if they observe sufficient output or know the seed state.

## Remediation

The fix replaces the insecure `random` module with Python's `secrets` module, which is designed for generating cryptographically secure random values. The `secrets.token_urlsafe(48)` function generates a URL-safe token with 48 bytes of randomness (resulting in a 64-character base64-encoded string), providing sufficient entropy for long-term IoT device authentication keys.

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

app = Flask(__name__)
iot_device_sessions = {}

@app.route('/api/iot/provision', methods=['POST'])
def provision_device():
    device_id = request.json.get('device_id')
    device_key = secrets.token_urlsafe(48)
    iot_device_sessions[device_id] = {'key': device_key, 'status': 'active'}
    return jsonify({'device_id': device_id, 'provisioning_key': device_key, 'expires': 86400})
```
