T09 · Insecure Skill Coding Practices
- Location
scripts/make_video.py:35- Finding
Arbitrary File Overwrite Through Output Path Traversal
- Content
View full analysis
Vulnerability Details
File Location:
scripts/make_video.py, lines 35-57
Vulnerability Type: Unrestricted output path and arbitrary file overwrite
Risk Level: Mediumpython def make_video(audio_path, image_path, output_video): """合成视频""" cmd = [ FFMPEG, "-loop", "1", "-i", image_path, "-i", audio_path, "-c:v", "libx264", "-tune", "stillimage", "-pix_fmt", "yuv420p", "-c:a", "aac", "-b:a", "128k", "-shortest", "-y", output_video ] subprocess.run(cmd, check=True) return output_video def main(): parser = argparse.ArgumentParser() parser.add_argument("--text", required=True, help="要朗读的文本") parser.add_argument("--bg_prompt", default="Beautiful elegant Chinese lady, soft lighting, cinematic, 4k", help="背景图描述") parser.add_argument("--output", default="result.mp4", help="输出文件名") args = parser.parse_args() audio_file = os.path.join(OUTPUT_DIR, "temp_audio.mp3") image_file = os.path.join(OUTPUT_DIR, "temp_bg.png") final_video = os.path.join(OUTPUT_DIR, args.output)Technical Analysis
The
--outputargument is accepted without validating that it is a simple filename. It is joined directly toOUTPUT_DIRusingos.path.join.An absolute path supplied as
args.outputcan causeos.path.jointo discard the intended base directory. Relative path components such as../can also resolve outsideOUTPUT_DIR. The resulting attacker-controlled path is passed to FFmpeg together with-y, which instructs FFmpeg to overwrite an existing destination without confirmation.Although the program uses an argument list rather than a shell command and is therefore not directly vulnerable to shell command injection, it does not enforce the intended filesystem boundary.
Attack Path
- An attacker or untrusted caller gains control over the value passed to
--output. - The attacker s ...[truncated 966 chars]
- An attacker or untrusted caller gains control over the value passed to
- Remediation
View remediation
Remediation Suggestions
- Treat
--outputstrictly as a filename rather than a path. - Reject absolute paths,
..components, directory separators, and unexpected file extensions. - Resolve the candidate destination with
os.path.realpathand verify that it remains beneath the canonical output directory. - Use
os.path.commonpathfor containment checks rather than string-prefix comparisons. - Allow only an expected extension such as
.mp4. - Avoid unconditional FFmpeg
-y; require an explicit overwrite option or fail if the destination already exists. - Run the media-generation process with a minimally privileged operating-system account.
Example hardening logic:
python output_root = os.path.realpath(OUTPUT_DIR) output_name = os.path.basename(args.output) if output_name != args.output or not output_name.lower().endswith(".mp4"): parser.error("--output must be a simple .mp4 filename") final_video = os.path.realpath(os.path.join(output_root, output_name)) if os.path.commonpath([output_root, final_video]) != output_root: parser.error("Output path escapes the designated output directory")- Treat
