{"title":"Unsafe YAML Deserialization via yaml.load()","language":"Python","severity":"Critical","cwe":"CWE-502","source_lines":[8],"flow_lines":[8,10],"sink_lines":[10],"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    try:\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        telemetry_interval = device_config.get('telemetry_interval', 60)\n        registry_entry = {\n            'id': device_id,\n            'firmware': firmware_ver,\n            'features': capabilities,\n            'interval': telemetry_interval,\n            'status': 'provisioned'\n        }\n        return jsonify({'success': True, 'device': registry_entry}), 200\n    except Exception as e:\n        return jsonify({'success': False, 'error': str(e)}), 400","explanation":"The application uses yaml.load() with yaml.Loader to deserialize untrusted YAML data from HTTP POST requests. This allows attackers to execute arbitrary Python code by crafting malicious YAML payloads that exploit Python's object serialization features, leading to Remote Code Execution (RCE).","remediation":"The fix replaces yaml.load() with yaml.safe_load(), which only deserializes standard YAML tags (strings, numbers, lists, dicts) and does not allow arbitrary Python object instantiation. Additionally, a type check ensures the parsed result is a dictionary before accessing keys, preventing unexpected behavior from non-mapping YAML inputs.","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    try:\n        device_config = yaml.safe_load(device_manifest)\n        if not isinstance(device_config, dict):\n            return jsonify({'success': False, 'error': 'Invalid 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        telemetry_interval = device_config.get('telemetry_interval', 60)\n        registry_entry = {\n            'id': device_id,\n            'firmware': firmware_ver,\n            'features': capabilities,\n            'interval': telemetry_interval,\n            'status': 'provisioned'\n        }\n        return jsonify({'success': True, 'device': registry_entry}), 200\n    except Exception as e:\n        return jsonify({'success': False, 'error': str(e)}), 400"}