# Insecure Temporary File Creation via tempfile.mktemp()

Language: Python
Severity: High
CWE: CWE-377

## Source
6

## Flow
6-7-9

## Sink
7

## Vulnerable Code
```python
import tempfile
import json
import os

def export_iot_device_telemetry(device_id, sensor_data):
    temp_path = tempfile.mktemp(suffix='.json', prefix=f'iot_telemetry_{device_id}_')
    with open(temp_path, 'w') as f:
        json.dump({'device': device_id, 'metrics': sensor_data, 'timestamp': sensor_data.get('ts')}, f)
    upload_to_cloud_storage(temp_path)
    os.remove(temp_path)
    return temp_path

def upload_to_cloud_storage(file_path):
    pass
```

## Explanation

The code uses tempfile.mktemp() which creates a predictable filename but doesn't actually create the file, leaving a race condition window between line 6 (getting the path) and line 7 (opening the file). An attacker can predict the filename and create a symlink or file at that path before line 7 executes, potentially redirecting sensitive IoT telemetry data to an attacker-controlled location or reading the data before it's uploaded.

## Remediation

Replaced tempfile.mktemp() with tempfile.mkstemp(), which atomically creates and opens the temporary file with exclusive access (O_EXCL), eliminating the race condition between filename generation and file creation. The file descriptor is wrapped with os.fdopen() for convenient writing, and cleanup is handled in a finally block to ensure the temp file is removed even if an error occurs during upload.

## Secure Code
```python
import tempfile
import json
import os

def export_iot_device_telemetry(device_id, sensor_data):
    fd, temp_path = tempfile.mkstemp(suffix='.json', prefix=f'iot_telemetry_{device_id}_')
    try:
        with os.fdopen(fd, 'w') as f:
            json.dump({'device': device_id, 'metrics': sensor_data, 'timestamp': sensor_data.get('ts')}, f)
        upload_to_cloud_storage(temp_path)
    finally:
        if os.path.exists(temp_path):
            os.remove(temp_path)
    return temp_path

def upload_to_cloud_storage(file_path):
    pass
```
