From 880c9c81cae3ff84cda8274b007151ae4c8bc26b Mon Sep 17 00:00:00 2001 From: sys-vdms <127380224+sys-vdms@users.noreply.github.com> Date: Wed, 21 Jan 2026 19:25:56 -0800 Subject: [PATCH] Potential fix for code scanning alert no. 2: Uncontrolled command line Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- video/info.py | 6 ++++-- video/utils.py | 10 +++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/video/info.py b/video/info.py index 09dbff7..f17ecde 100755 --- a/video/info.py +++ b/video/info.py @@ -24,6 +24,7 @@ def check_origin(self, origin): def _get_info(self, video): width = height = duration = fps = nb_frames = 0 + input_path = safely_join_path(self._mp4path, video) cmd = [ "/usr/local/bin/ffprobe", "-v", @@ -33,7 +34,7 @@ def _get_info(self, video): "-count_frames", "-show_streams", "-i", - safely_join_path(self._mp4path, video), + input_path, ] with Popen( cmd, stdout=PIPE, stderr=STDOUT, bufsize=1, universal_newlines=True @@ -56,8 +57,9 @@ def _get_info(self, video): fps = float(eq[0]) / float(eq[1]) if line.startswith("nb_read_frames="): nb_frames = int(line.split("=")[-1]) - p.stdout.close() p.wait() + if p.returncode != 0: + raise RuntimeError(f"ffprobe failed for input {input_path!r} with code {p.returncode}") if fps == 0 and (nb_frames != 0 and duration != 0): fps = nb_frames / duration return { diff --git a/video/utils.py b/video/utils.py index d04fc90..20ab543 100644 --- a/video/utils.py +++ b/video/utils.py @@ -1,5 +1,5 @@ import os - +import re def safely_join_path(base_dir, add_path): safe_base = os.path.abspath(base_dir) @@ -34,5 +34,13 @@ def validate_video_name(name): raise ValueError("Video name cannot be empty") # Disallow path separators to ensure this is just a file name. if os.sep in cleaned or "/" in cleaned or "\\" in cleaned: + # Restrict the video name to a safe subset of characters to avoid + # passing arbitrary strings to external commands. + # Allow letters, digits, underscore, hyphen and dot, and disallow + # leading dot to avoid hidden or special files. + if cleaned.startswith("."): + raise ValueError(f"Invalid video name: {cleaned}") + if not re.fullmatch(r"[A-Za-z0-9._-]+", cleaned): + raise ValueError(f"Invalid video name: {cleaned}") raise ValueError(f"Invalid video name: {cleaned}") return cleaned