{"title":"Insecure Randomness via random for Session Token Generation","language":"Python","severity":"High","cwe":"CWE-338","source_lines":[12],"flow_lines":[12],"sink_lines":[12],"vulnerable_code":"import random\nimport string\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    auth_token = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32))\n    iot_device_sessions[device_id] = {\n        'token': auth_token,\n        'type': device_type,\n        'provisioned_at': time.time()\n    }\n    return jsonify({\n        'status': 'provisioned',\n        'device_id': device_id,\n        'auth_token': auth_token,\n        'endpoint': f'/api/iot/data/{device_id}'\n    })","explanation":"The code uses Python's random module to generate authentication tokens for IoT devices. The random module is not cryptographically secure and uses a predictable Mersenne Twister PRNG, making tokens guessable by attackers who can observe a sequence of tokens or predict the internal state.","remediation":"The fix replaces the insecure `random.choice()` token generation with `secrets.token_urlsafe(32)`, which uses a cryptographically secure random number generator (CSPRNG). The `secrets` module is specifically designed for generating tokens, passwords, and other security-sensitive random values, making the generated auth tokens unpredictable and resistant to brute-force or prediction attacks. Additionally, the missing `import time` was added to fix the runtime error.","secure_code":"import secrets\nimport string\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    auth_token = secrets.token_urlsafe(32)\n    iot_device_sessions[device_id] = {\n        'token': auth_token,\n        'type': device_type,\n        'provisioned_at': time.time()\n    }\n    return jsonify({\n        'status': 'provisioned',\n        'device_id': device_id,\n        'auth_token': auth_token,\n        'endpoint': f'/api/iot/data/{device_id}'\n    })"}