{"title":"Insecure Temporary File Creation via Race Condition in mktemp() (TOCTOU)","language":"Python","severity":"High","cwe":"CWE-377","source_lines":[3],"flow_lines":[3,4,5],"sink_lines":[5],"vulnerable_code":"import tempfile, os\ndef cache_sensor_payload(device_id, raw_data):\n    tmp_path = tempfile.mktemp(suffix='.bin', prefix=f'iot_{device_id}_')\n    if not os.path.exists(tmp_path):\n        with open(tmp_path, 'wb') as fh:\n            fh.write(raw_data)\n    parsed = parse_binary_frame(tmp_path)\n    os.remove(tmp_path)\n    return parsed","explanation":"tempfile.mktemp() returns a filename without atomically creating the file, introducing a Time-Of-Check-Time-Of-Use (TOCTOU) race condition. The os.path.exists() check on line 4 further widens the window between name generation and file creation, allowing an attacker to place a symlink or malicious file at tmp_path before open() is called on line 5, enabling arbitrary file writes or data injection.","remediation":"Replaced `tempfile.mktemp()` with `tempfile.mkstemp()`, which atomically creates the file and returns an open file descriptor, eliminating the TOCTOU race condition. The file descriptor is wrapped with `os.fdopen()` for writing, and cleanup is placed in a `finally` block to ensure the temporary file is always removed. The redundant `os.path.exists()` check was also removed since `mkstemp()` guarantees the file is created exclusively.","secure_code":"import tempfile, os\ndef cache_sensor_payload(device_id, raw_data):\n    fd, tmp_path = tempfile.mkstemp(suffix='.bin', prefix=f'iot_{device_id}_')\n    try:\n        with os.fdopen(fd, 'wb') as fh:\n            fh.write(raw_data)\n        parsed = parse_binary_frame(tmp_path)\n    finally:\n        os.remove(tmp_path)\n    return parsed"}