# Insecure Randomness via random.choice() for Session Token Generation

Language: Python
Severity: High
CWE: CWE-338

## Source
5

## Flow
5-7-8

## Sink
7

## Vulnerable Code
```python
import random
import string

def provision_iot_device_auth(device_mac, device_type):
    charset = string.ascii_letters + string.digits
    device_token = ''.join(random.choice(charset) for _ in range(32))
    device_registry = {'mac': device_mac, 'type': device_type, 'auth_token': device_token, 'provisioned': True}
    store_device_credentials(device_registry)
    return device_token

def store_device_credentials(registry):
    with open(f"/var/iot/devices/{registry['mac']}.conf", 'w') as f:
        f.write(f"TOKEN={registry['auth_token']}")
```

## Explanation

The code uses Python's random.choice() from the random module to generate a 32-character authentication token for IoT devices. The random module uses a pseudorandom number generator (Mersenne Twister) that is not cryptographically secure, making tokens predictable and susceptible to brute-force or prediction attacks by adversaries who can observe multiple tokens.

## Remediation

The fix replaces the insecure `random.choice()` with `secrets.choice()` from Python's `secrets` module, which uses a cryptographically secure random number generator (CSPRNG). This ensures that generated IoT device authentication tokens are unpredictable and resistant to prediction attacks, even if an attacker observes multiple previously generated tokens.

## Secure Code
```python
import secrets
import string

def provision_iot_device_auth(device_mac, device_type):
    charset = string.ascii_letters + string.digits
    device_token = ''.join(secrets.choice(charset) for _ in range(32))
    device_registry = {'mac': device_mac, 'type': device_type, 'auth_token': device_token, 'provisioned': True}
    store_device_credentials(device_registry)
    return device_token

def store_device_credentials(registry):
    with open(f"/var/iot/devices/{registry['mac']}.conf", 'w') as f:
        f.write(f"TOKEN={registry['auth_token']}")
```
