# Insecure Temporary File Creation via tempfile.mktemp()

Language: Python
Severity: High
CWE: CWE-377

## Source
5

## Flow
5-13

## Sink
13

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

def store_iot_sensor_telemetry(device_id, temperature, humidity, pressure):
    temp_path = tempfile.mktemp(suffix='.json', prefix=f'iot_{device_id}_')
    telemetry_data = {
        'device': device_id,
        'temp': temperature,
        'humidity': humidity,
        'pressure': pressure
    }
    with open(temp_path, 'w') as f:
        json.dump(telemetry_data, f)
    os.system(f'curl -X POST https://cloud.iot-platform.com/ingest -d @{temp_path}')
    return temp_path
```

## Explanation

The code uses tempfile.mktemp() which creates a predictable temporary filename without actually creating the file, allowing race condition attacks where an attacker can create a malicious file at that path before the legitimate code does. Additionally, the temp_path is used directly in os.system() with shell expansion, creating a command injection vulnerability if device_id contains shell metacharacters.

## Remediation

The fix replaces tempfile.mktemp() with tempfile.mkstemp() which atomically creates the file with restrictive permissions (0600), eliminating the race condition vulnerability. It also replaces os.system() with subprocess.run() using an argument list to prevent shell injection, and adds input validation on device_id to ensure only safe characters are used in file paths and commands.

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

def store_iot_sensor_telemetry(device_id, temperature, humidity, pressure):
    # Validate device_id to prevent injection attacks
    if not re.match(r'^[a-zA-Z0-9_-]+$', str(device_id)):
        raise ValueError("Invalid device_id: only alphanumeric characters, hyphens, and underscores are allowed")
    
    telemetry_data = {
        'device': device_id,
        'temp': temperature,
        'humidity': humidity,
        'pressure': pressure
    }
    
    # Use mkstemp() which atomically creates the file with secure permissions
    fd, temp_path = tempfile.mkstemp(suffix='.json', prefix=f'iot_{device_id}_')
    try:
        with os.fdopen(fd, 'w') as f:
            json.dump(telemetry_data, f)
        
        # Use subprocess with argument list to avoid shell injection
        subprocess.run(
            ['curl', '-X', 'POST', 'https://cloud.iot-platform.com/ingest', '-d', f'@{temp_path}'],
            check=True,
            capture_output=True
        )
    finally:
        # Clean up the temporary file
        if os.path.exists(temp_path):
            os.unlink(temp_path)
    
    return temp_path
```
