{"title":"Insecure Randomness via random.randint for Password Reset Tokens","language":"Python","severity":"High","cwe":"CWE-338","source_lines":[11],"flow_lines":[11,12],"sink_lines":[12],"vulnerable_code":"import random\nimport hashlib\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n@app.route('/api/iot/device/reset-auth', methods=['POST'])\ndef reset_device_credentials():\n    device_id = request.json.get('device_id')\n    reset_code = random.randint(100000, 999999)\n    auth_token = hashlib.sha256(f\"{device_id}:{reset_code}\".encode()).hexdigest()\n    store_reset_token(device_id, auth_token, reset_code)\n    send_sms_to_device_owner(device_id, reset_code)\n    return jsonify({\"status\": \"success\", \"message\": \"Reset code sent to registered mobile\"})\n\ndef store_reset_token(dev_id, token, code):\n    pass\n\ndef send_sms_to_device_owner(dev_id, code):\n    pass","explanation":"The code uses Python's random.randint() to generate a 6-digit password reset code, which relies on the Mersenne Twister PRNG that is cryptographically insecure and predictable. An attacker can predict future reset codes by observing previous codes, allowing unauthorized device credential resets and account takeover.","remediation":"The fix replaces the insecure `random.randint()` with `secrets.randbelow()` from Python's `secrets` module, which uses a cryptographically secure random number generator (CSPRNG). The expression `secrets.randbelow(900000) + 100000` produces the same range of 6-digit codes (100000-999999) but with unpredictable randomness that cannot be reverse-engineered from observed outputs.","secure_code":"import secrets\nimport hashlib\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n@app.route('/api/iot/device/reset-auth', methods=['POST'])\ndef reset_device_credentials():\n    device_id = request.json.get('device_id')\n    reset_code = secrets.randbelow(900000) + 100000\n    auth_token = hashlib.sha256(f\"{device_id}:{reset_code}\".encode()).hexdigest()\n    store_reset_token(device_id, auth_token, reset_code)\n    send_sms_to_device_owner(device_id, reset_code)\n    return jsonify({\"status\": \"success\", \"message\": \"Reset code sent to registered mobile\"})\n\ndef store_reset_token(dev_id, token, code):\n    pass\n\ndef send_sms_to_device_owner(dev_id, code):\n    pass"}