T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/tencent_tts.py:115
- Finding
- Unrestricted Output Path Allows Arbitrary File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/tencent_tts.py`, lines 115-118 and 175-176 **Vulnerability Type**: Unrestricted file path and unsafe overwrite **Risk Level**: Medium ### Vulnerable Code ```python def synthesize(self, text, voice_type=101001, codec="mp3", output_file="output.mp3"): ``` ```python audio_bytes = base64.b64decode(audio_data) with open(output_file, "wb") as f: f.write(audio_bytes) ``` ### Technical Analysis The `output_file` parameter is used directly as a filesystem path without validating, normalizing, or restricting it to an approved output directory. Python's `"wb"` mode creates a missing file or truncates an existing file before writing the audio response. Consequently, a caller that controls `output_file` can provide an absolute path or a path containing traversal sequences such as `../`. The write occurs after a successful Tencent Cloud response, so exploitation requires valid credentials, network access, and a successful synthesis request. The attacker cannot use this flaw to choose arbitrary file contents because the written bytes are the audio returned by Tencent Cloud. However, the attacker can still destroy or corrupt existing files by replacing them with audio data. ### Attack Path 1. An attacker gains influence over the `output_file` argument through an application or agent that exposes the Skill. 2. The attacker supplies an absolute or traversal path, such as `../../application/config.py`. 3. The Skill submits an otherwise valid synthesis request to Tencent Cloud. 4. Tencent Cloud returns a successful response containing Base64-encoded audio. 5. The Skill opens the attacker-selected path using `"wb"`. 6. Any existing target file is truncated and replaced with the decoded audio. ### Impact Assessment The vulnerability permits file creation, truncation, and overwrite with the privileges of the process running the Skill. Potential consequenc ...[truncated 448 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Define a dedicated audio output directory controlled by the application. - Reject absolute paths and parent-directory traversal components. - Resolve the requested path and verify that it remains beneath the approved directory: ```python from pathlib import Path output_dir = Path("./audio_output").resolve() output_dir.mkdir(mode=0o700, parents=True, exist_ok=True) requested_name = Path(output_file) if requested_name.is_absolute(): raise ValueError("Absolute output paths are not allowed") resolved_output = (output_dir / requested_name).resolve() if output_dir not in resolved_output.parents: raise ValueError("Output path escapes the approved directory") ``` - Accept a filename rather than an unrestricted path when directory selection is unnecessary. - Use exclusive creation mode (`"xb"`) by default to prevent silent replacement of existing files. - If overwrite functionality is required, make it an explicit option and obtain confirmation before replacing a file. - Apply restrictive file permissions and run the Skill under a least-privileged operating-system account. - Add tests covering absolute paths, `../` traversal, symlink-based escapes, and attempts to overwrite existing files. ]]>
