{"title":"Unsafe YAML Deserialization via yaml.load() on Untrusted Input","language":"Python","severity":"Critical","cwe":"CWE-502","source_lines":[8],"flow_lines":[8,9],"sink_lines":[9],"vulnerable_code":"import yaml\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n@app.route('/iot/device/provision', methods=['POST'])\ndef provision_iot_device():\n    device_manifest = request.data.decode('utf-8')\n    device_config = yaml.load(device_manifest, Loader=yaml.Loader)\n    device_id = device_config.get('device_id', 'unknown')\n    firmware_version = device_config.get('firmware', '1.0.0')\n    security_profile = device_config.get('security_profile', {})\n    print(f\"Provisioning device {device_id} with firmware {firmware_version}\")\n    return jsonify({\"status\": \"provisioned\", \"device_id\": device_id, \"profile\": security_profile})","explanation":"The application uses yaml.load() with yaml.Loader on untrusted user input from request.data without validation. This allows arbitrary Python object instantiation, enabling remote code execution through malicious YAML payloads containing Python object constructors.","remediation":"The fix replaces yaml.load() with yaml.safe_load(), which only deserializes standard YAML tags (strings, numbers, lists, dicts) and refuses to instantiate arbitrary Python objects. An additional type check ensures the parsed result is a dictionary, preventing unexpected input types from causing downstream errors.","secure_code":"import yaml\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n@app.route('/iot/device/provision', methods=['POST'])\ndef provision_iot_device():\n    device_manifest = request.data.decode('utf-8')\n    device_config = yaml.safe_load(device_manifest)\n    if not isinstance(device_config, dict):\n        return jsonify({\"error\": \"Invalid device manifest format\"}), 400\n    device_id = device_config.get('device_id', 'unknown')\n    firmware_version = device_config.get('firmware', '1.0.0')\n    security_profile = device_config.get('security_profile', {})\n    print(f\"Provisioning device {device_id} with firmware {firmware_version}\")\n    return jsonify({\"status\": \"provisioned\", \"device_id\": device_id, \"profile\": security_profile})"}