# Insecure Random Token Generation via `random` for Session IDs

Language: Python
Severity: High
CWE: CWE-338

## Source
9

## Flow
9-11

## Sink
11

## Vulnerable Code
```python
import random
import string
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')
    auth_token = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32))
    iot_device_sessions[device_id] = {'token': auth_token, 'provisioned': True}
    return jsonify({'device_id': device_id, 'auth_token': auth_token, 'status': 'provisioned'})
```

## Explanation

The code uses Python's `random` module to generate authentication tokens for IoT devices. The `random` module uses a Mersenne Twister PRNG that is cryptographically weak and predictable, allowing attackers to predict future tokens by observing previous ones, enabling device impersonation and unauthorized access.

## Remediation

The fix replaces the insecure `random` module with Python's `secrets` module, which is specifically designed for generating cryptographically strong random values suitable for security-sensitive applications like token generation. The `secrets.token_urlsafe(32)` function generates a URL-safe base64-encoded token with 32 bytes of randomness, providing sufficient entropy to prevent prediction attacks.

## Secure Code
```python
import secrets
import string
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')
    auth_token = secrets.token_urlsafe(32)
    iot_device_sessions[device_id] = {'token': auth_token, 'provisioned': True}
    return jsonify({'device_id': device_id, 'auth_token': auth_token, 'status': 'provisioned'})
```
