{"title":"Insecure Temporary File Creation via tempfile.mktemp","language":"Python","severity":"High","cwe":"CWE-377","source_lines":[5],"flow_lines":[5,13],"sink_lines":[13],"vulnerable_code":"import tempfile\nimport json\nimport os\n\ndef store_iot_sensor_telemetry(device_id, temperature, humidity, pressure):\n    telemetry_cache = tempfile.mktemp(suffix='.json', prefix=f'iot_{device_id}_')\n    sensor_data = {\n        'device': device_id,\n        'temp': temperature,\n        'humidity': humidity,\n        'pressure': pressure\n    }\n    with open(telemetry_cache, 'w') as f:\n        json.dump(sensor_data, f)\n    os.system(f'curl -X POST https://cloud.iot-platform.com/ingest -d @{telemetry_cache}')\n    os.remove(telemetry_cache)\n    return telemetry_cache","explanation":"The code uses the deprecated tempfile.mktemp() which creates a predictable filename without atomically creating the file, leading to a race condition vulnerability (TOCTOU - Time of Check Time of Use). An attacker can predict the filename and create a malicious file or symlink at that path before the legitimate code opens it. Additionally, the predictable filename is directly interpolated into an os.system() command, enabling command injection if an attacker controls the file path or creates a malicious filename.","remediation":"The fix replaces tempfile.mktemp() with tempfile.NamedTemporaryFile(delete=False) which atomically creates the file with secure permissions, eliminating the TOCTOU race condition. It also replaces os.system() with subprocess.run() using an argument list to prevent command injection, and adds input validation on device_id to reject malicious characters.","secure_code":"import tempfile\nimport json\nimport os\nimport subprocess\nimport re\n\ndef store_iot_sensor_telemetry(device_id, temperature, humidity, pressure):\n    # Validate device_id to prevent injection attacks\n    if not re.match(r'^[a-zA-Z0-9_\\-]+$', str(device_id)):\n        raise ValueError(\"Invalid device_id: must contain only alphanumeric characters, hyphens, and underscores\")\n    \n    sensor_data = {\n        'device': device_id,\n        'temp': temperature,\n        'humidity': humidity,\n        'pressure': pressure\n    }\n    \n    # Use NamedTemporaryFile to atomically create the file with secure permissions\n    with tempfile.NamedTemporaryFile(mode='w', suffix='.json', prefix=f'iot_{device_id}_',\n                                      delete=False, dir=None) as f:\n        telemetry_cache = f.name\n        os.chmod(telemetry_cache, 0o600)\n        json.dump(sensor_data, f)\n    \n    try:\n        # Use subprocess with argument list to prevent command injection\n        subprocess.run(\n            ['curl', '-X', 'POST', 'https://cloud.iot-platform.com/ingest',\n             '-d', f'@{telemetry_cache}'],\n            check=True,\n            timeout=30\n        )\n    finally:\n        # Ensure temp file is always cleaned up\n        if os.path.exists(telemetry_cache):\n            os.remove(telemetry_cache)\n    \n    return telemetry_cache"}