# Insecure Randomness via random.random() for API Key Generation

Language: Python
Severity: Critical
CWE: CWE-338

## Source
9

## Flow
9-10-11

## Sink
11

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

app = Flask(__name__)

@app.route('/provision/iot-device', methods=['POST'])
def provision_iot_device():
    device_secret = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(48))
    device_id = f"IOT-{random.randint(100000, 999999)}"
    mqtt_token = hex(int(random.random() * (10**16)))[2:]
    return jsonify({"device_id": device_id, "secret_key": device_secret, "mqtt_auth_token": mqtt_token})
```

## Explanation

The code uses Python's random module (random.choice(), random.randint(), random.random()) to generate cryptographic secrets for IoT device authentication. The random module uses a Mersenne Twister PRNG which is not cryptographically secure and predictable, allowing attackers to predict future device credentials after observing a sequence of generated values.

## Remediation

The fix replaces all uses of the insecure `random` module with Python's `secrets` module, which is designed for generating cryptographically secure random values. `secrets.choice()` replaces `random.choice()` for the device secret, `secrets.randbelow()` replaces `random.randint()` for the device ID, and `secrets.token_hex()` replaces the `random.random()` hack for the MQTT token.

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

app = Flask(__name__)

@app.route('/provision/iot-device', methods=['POST'])
def provision_iot_device():
    device_secret = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(48))
    device_id = f"IOT-{secrets.randbelow(900000) + 100000}"
    mqtt_token = secrets.token_hex(16)
    return jsonify({"device_id": device_id, "secret_key": device_secret, "mqtt_auth_token": mqtt_token})
```
