T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:94
- Finding
- Predictable Temporary File Permits Symlink-Based File Overwrite## Vulnerability Details **File Location**: `SKILL.md`, lines 94–95 **Vulnerability Type**: Predictable temporary file and unsafe file creation **Risk Level**: Medium ### Vulnerable Code ```python open('/tmp/translated.mp3','wb').write(audio) subprocess.run(['play','/tmp/translated.mp3']) ``` ### Technical Analysis The documented TTS pipeline writes generated audio to a fixed path in the shared `/tmp` directory. The call to `open(..., 'wb')` follows symbolic links and does not create the file with exclusive semantics. A local attacker who can write to `/tmp` can create `/tmp/translated.mp3` as a symbolic link to another file before the pipeline runs. If the target file is writable by the user executing the example, the write operation truncates and replaces its contents with generated audio. The fixed filename also allows concurrent translator runs to overwrite or play each other's output. The example does not remove the file after playback, so translated speech remains locally accessible subject to the resulting file permissions and host configuration. ### Attack Path 1. A local attacker identifies that the user intends to run the documented TTS command. 2. The attacker creates `/tmp/translated.mp3` as a symbolic link to a file writable by that user. 3. The user runs the pipeline and receives valid audio data from the TTS API. 4. Python opens the predictable path in write mode and follows the attacker's symbolic link. 5. The linked target is truncated and overwritten with audio bytes. 6. The subsequent `play` command accesses the same attacker-controlled path. This exploitation path requires local access to the shared temporary directory and a target writable under the victim process's existing privileges. ### Impact Assessment The vulnerability does not grant privileges beyond those already held by the process. It can nevertheless let a local attacker overwrite or corrupt any file writable by the user runn ...[truncated 530 chars]
- Remediation
- ## Remediation Suggestions - Replace the fixed path with a securely generated temporary file, preferably through `tempfile.NamedTemporaryFile`. - Create the file with restrictive permissions and exclusive creation semantics. - Pass the generated path to the player as an argument list rather than constructing a shell command. - Delete the temporary recording in a `finally` block after playback, including when playback fails. - Keep the file descriptor or file lifecycle under the process's control to minimize time-of-check/time-of-use races. - For example: ```python import os import subprocess import tempfile tmp_path = None try: with tempfile.NamedTemporaryFile( mode="wb", suffix=".mp3", prefix="senseaudio-", delete=False, ) as audio_file: audio_file.write(audio) tmp_path = audio_file.name subprocess.run(["play", tmp_path], check=True) finally: if tmp_path is not None: try: os.unlink(tmp_path) except FileNotFoundError: pass ``` - Clearly disclose that recordings and translated text are sent to the external SenseAudio service, and obtain user consent before upload.
