{"title":"Insecure Temporary File Creation via tempfile.mktemp()","language":"Python","severity":"High","cwe":"CWE-377","source_lines":[6],"flow_lines":[6,13],"sink_lines":[13],"vulnerable_code":"import tempfile\nimport json\nimport os\n\ndef export_iot_device_telemetry(device_id, sensor_data):\n    temp_path = tempfile.mktemp(suffix='.json', prefix=f'iot_telemetry_{device_id}_')\n    telemetry_payload = {\n        'device_id': device_id,\n        'timestamp': sensor_data.get('timestamp'),\n        'temperature': sensor_data.get('temp'),\n        'humidity': sensor_data.get('humidity'),\n        'api_key': os.getenv('IOT_API_KEY')\n    }\n    with open(temp_path, 'w') as f:\n        json.dump(telemetry_payload, f)\n    return temp_path","explanation":"The code uses tempfile.mktemp() which creates a predictable temporary filename without atomically creating the file, leading to a TOCTOU (Time-of-Check-Time-of-Use) race condition. An attacker can predict the filename and create a symlink at that location between mktemp() returning and the open() call on line 12, allowing them to redirect sensitive telemetry data (including the IOT_API_KEY) to an attacker-controlled file or overwrite critical system files.","remediation":"Replaced tempfile.mktemp() with tempfile.mkstemp(), which atomically creates the file and returns both a file descriptor and the path. This eliminates the TOCTOU race condition because the file is created with exclusive access (O_EXCL) at the time the name is generated, preventing symlink attacks. The file descriptor is wrapped with os.fdopen() to write the JSON payload safely.","secure_code":"import tempfile\nimport json\nimport os\n\ndef export_iot_device_telemetry(device_id, sensor_data):\n    telemetry_payload = {\n        'device_id': device_id,\n        'timestamp': sensor_data.get('timestamp'),\n        'temperature': sensor_data.get('temp'),\n        'humidity': sensor_data.get('humidity'),\n        'api_key': os.getenv('IOT_API_KEY')\n    }\n    fd, temp_path = tempfile.mkstemp(suffix='.json', prefix=f'iot_telemetry_{device_id}_')\n    try:\n        with os.fdopen(fd, 'w') as f:\n            json.dump(telemetry_payload, f)\n    except Exception:\n        os.unlink(temp_path)\n        raise\n    return temp_path"}