# Insecure Randomness via random.choice for Session Token Generation

Language: Python
Severity: High
CWE: CWE-338

## Source
10

## Flow
10-11

## Sink
11

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

app = Flask(__name__)
app.secret_key = 'dev_key_12345'

@app.route('/iot/device/pair', methods=['POST'])
def pair_iot_device():
    device_id = request.json.get('device_id')
    pairing_token = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(16))
    session['iot_pairing_token'] = pairing_token
    session['paired_device'] = device_id
    return {'pairing_token': pairing_token, 'device_id': device_id, 'status': 'pending_confirmation'}
```

## Explanation

The code uses Python's random.choice() from the random module to generate a pairing token for IoT device authentication. The random module uses a Mersenne Twister PRNG which is not cryptographically secure and predictable, making the 16-character token vulnerable to prediction attacks during the critical device pairing phase.

## Remediation

The fix replaces the insecure random.choice() with Python's secrets module, which provides cryptographically secure random number generation suitable for security-sensitive token creation. Additionally, the hardcoded app.secret_key was replaced with a securely generated key using secrets.token_hex(32), and secrets.token_urlsafe(24) generates a 32-character URL-safe token with sufficient entropy to resist prediction attacks.

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

app = Flask(__name__)
app.secret_key = secrets.token_hex(32)

@app.route('/iot/device/pair', methods=['POST'])
def pair_iot_device():
    device_id = request.json.get('device_id')
    pairing_token = secrets.token_urlsafe(24)
    session['iot_pairing_token'] = pairing_token
    session['paired_device'] = device_id
    return {'pairing_token': pairing_token, 'device_id': device_id, 'status': 'pending_confirmation'}
```
