# Insecure Session Token Generation via random.random()

Language: Python
Severity: High
CWE: CWE-338

## Source
11

## Flow
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_smart_device():
    device_id = request.json.get('device_id')
    device_type = request.json.get('type')
    nonce = str(random.random() * 999999)
    provision_token = hashlib.sha256(f"{device_id}:{nonce}".encode()).hexdigest()
    iot_device_sessions[device_id] = {'token': provision_token, 'type': device_type}
    return jsonify({'provision_token': provision_token, 'status': 'provisioned'})
```

## Explanation

The code uses random.random() to generate a nonce for session tokens, which is cryptographically weak and predictable. Python's random module uses the Mersenne Twister algorithm, which is not suitable for security purposes as attackers can predict future values after observing a sequence of outputs, allowing them to forge valid provision tokens for IoT devices.

## Remediation

The fix replaces the insecure `random.random()` call with `secrets.token_hex(32)`, which generates a cryptographically secure random nonce using the operating system's CSPRNG. This ensures that the nonce cannot be predicted by an attacker even if they observe previous token values, making it impossible to forge valid provision tokens for IoT devices.

## 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_smart_device():
    device_id = request.json.get('device_id')
    device_type = request.json.get('type')
    nonce = secrets.token_hex(32)
    provision_token = hashlib.sha256(f"{device_id}:{nonce}".encode()).hexdigest()
    iot_device_sessions[device_id] = {'token': provision_token, 'type': device_type}
    return jsonify({'provision_token': provision_token, 'status': 'provisioned'})
```
