{"title":"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_ver = device_config.get('firmware_version', '1.0.0')\n    capabilities = device_config.get('capabilities', [])\n    print(f\"Provisioning device {device_id} with firmware {firmware_ver}\")\n    return jsonify({'status': 'provisioned', 'device_id': device_id, 'capabilities': capabilities})","explanation":"The application uses yaml.load() with yaml.Loader on untrusted user input from request.data without validation. This allows arbitrary Python object instantiation during YAML deserialization, enabling remote code execution through specially crafted YAML payloads containing malicious Python objects.","remediation":"The fix replaces yaml.load() with yaml.safe_load(), which only deserializes standard YAML tags (strings, numbers, lists, dicts) and prevents instantiation of arbitrary Python objects. Additionally, a type check ensures the parsed YAML is a dictionary before accessing its keys, providing defense against unexpected input formats.","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({'status': 'error', 'message': 'Invalid device manifest format'}), 400\n    device_id = device_config.get('device_id', 'unknown')\n    firmware_ver = device_config.get('firmware_version', '1.0.0')\n    capabilities = device_config.get('capabilities', [])\n    print(f\"Provisioning device {device_id} with firmware {firmware_ver}\")\n    return jsonify({'status': 'provisioned', 'device_id': device_id, 'capabilities': capabilities})"}