# Insecure Randomness via random for Session Token Generation

Language: Python
Severity: High
CWE: CWE-338

## Source
12

## Flow
12

## Sink
12

## 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_type = request.json.get('type')
    auth_token = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32))
    iot_device_sessions[device_id] = {
        'token': auth_token,
        'type': device_type,
        'provisioned_at': time.time()
    }
    return jsonify({
        'status': 'provisioned',
        'device_id': device_id,
        'auth_token': auth_token,
        'endpoint': f'/api/iot/data/{device_id}'
    })
```

## Explanation

The code uses Python's random module to generate authentication tokens for IoT devices. The random module is not cryptographically secure and uses a predictable Mersenne Twister PRNG, making tokens guessable by attackers who can observe a sequence of tokens or predict the internal state.

## Remediation

The fix replaces the insecure `random.choice()` token generation with `secrets.token_urlsafe(32)`, which uses a cryptographically secure random number generator (CSPRNG). The `secrets` module is specifically designed for generating tokens, passwords, and other security-sensitive random values, making the generated auth tokens unpredictable and resistant to brute-force or prediction attacks. Additionally, the missing `import time` was added to fix the runtime error.

## Secure Code
```python
import secrets
import string
import time
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_type = request.json.get('type')
    auth_token = secrets.token_urlsafe(32)
    iot_device_sessions[device_id] = {
        'token': auth_token,
        'type': device_type,
        'provisioned_at': time.time()
    }
    return jsonify({
        'status': 'provisioned',
        'device_id': device_id,
        'auth_token': auth_token,
        'endpoint': f'/api/iot/data/{device_id}'
    })
```
