{"title":"Insecure Randomness via random.random() for Session Token Generation","language":"Python","severity":"High","cwe":"CWE-338","source_lines":[12],"flow_lines":[12,14],"sink_lines":[14],"vulnerable_code":"import random\nimport hashlib\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\niot_device_sessions = {}\n\n@app.route('/api/iot/provision', methods=['POST'])\ndef provision_device():\n    device_id = request.json.get('device_id')\n    device_type = request.json.get('type')\n    rand_seed = int(random.random() * 1000000000)\n    nonce = random.randint(100000, 999999)\n    auth_token = hashlib.sha256(f\"{device_id}:{rand_seed}:{nonce}\".encode()).hexdigest()\n    iot_device_sessions[device_id] = {\n        'token': auth_token,\n        'type': device_type,\n        'provisioned_at': str(random.random())\n    }\n    return jsonify({\n        'status': 'provisioned',\n        'auth_token': auth_token,\n        'device_id': device_id\n    })","explanation":"The code uses Python's random.random() and random.randint() for generating cryptographic tokens, which are not cryptographically secure PRNGs. These functions use the Mersenne Twister algorithm that is predictable and can be cracked, allowing attackers to predict authentication tokens for IoT devices.","remediation":"The fix replaces all uses of the insecure `random` module with Python's `secrets` module, which provides cryptographically secure random number generation suitable for authentication tokens. The `secrets.token_hex()` function generates unpredictable random bytes, making it infeasible for attackers to predict or reproduce generated tokens. Additionally, the `provisioned_at` field now uses `time.time()` instead of `random.random()` for a meaningful timestamp.","secure_code":"import secrets\nimport hashlib\nimport time\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\niot_device_sessions = {}\n\n@app.route('/api/iot/provision', methods=['POST'])\ndef provision_device():\n    device_id = request.json.get('device_id')\n    device_type = request.json.get('type')\n    rand_seed = secrets.token_hex(32)\n    nonce = secrets.token_hex(16)\n    auth_token = hashlib.sha256(f\"{device_id}:{rand_seed}:{nonce}\".encode()).hexdigest()\n    iot_device_sessions[device_id] = {\n        'token': auth_token,\n        'type': device_type,\n        'provisioned_at': str(time.time())\n    }\n    return jsonify({\n        'status': 'provisioned',\n        'auth_token': auth_token,\n        'device_id': device_id\n    })"}