# Race Condition via TOCTOU in Temporary File Creation

Language: Python
Severity: High
CWE: CWE-367

## Source
5

## Flow
5-6-7

## Sink
7

## Vulnerable Code
```python
import os
import tempfile
def store_iot_telemetry(device_id, payload):
    tmp_dir = tempfile.gettempdir()
    sensor_file = os.path.join(tmp_dir, f'sensor_{device_id}.dat')
    if not os.path.exists(sensor_file):
        with open(sensor_file, 'w') as fh:
            fh.write(payload)
        os.chmod(sensor_file, 0o644)
        return sensor_file
    return None
```

## Explanation

The code constructs a predictable temporary file path using a device_id (line 5), then performs a TOCTOU (Time-Of-Check-Time-Of-Use) race: it checks if the file exists (line 6) and then opens/writes to it (line 7). Between the os.path.exists() check and the open() call, an attacker can create a symbolic link at the target path (e.g., /tmp/sensor_<device_id>.dat -> /etc/cron.d/backdoor), causing the service to write attacker-influenced payload data to an arbitrary privileged file.

## Remediation

The fix replaces the TOCTOU-vulnerable check-then-act pattern (os.path.exists followed by open) with tempfile.mkstemp(), which atomically creates and opens a new unique temporary file with a secure file descriptor, eliminating the race window. The file descriptor is immediately wrapped with os.fdopen to write the payload, preventing any symlink attack between check and use. Additionally, permissions are tightened from 0o644 to 0o600 to restrict access to only the owning process.

## Secure Code
```python
import os
import tempfile
def store_iot_telemetry(device_id, payload):
    tmp_dir = tempfile.gettempdir()
    prefix = f'sensor_{device_id}_'
    try:
        fd = tempfile.mkstemp(prefix=prefix, suffix='.dat', dir=tmp_dir)
        file_descriptor, sensor_file = fd
        with os.fdopen(file_descriptor, 'w') as fh:
            fh.write(payload)
        os.chmod(sensor_file, 0o600)
        return sensor_file
    except OSError:
        return None
```
