Harden subprocess argv against option injection (#2)

- download.py: insert `--` before URL in yt-dlp argv so a `-`-prefixed
  string can never be parsed as a flag (e.g. --exec, --config-location).
  Tighten is_url to reject `-`-prefixed sources and require non-empty
  netloc.
- frames.py, whisper.py: resolve video/audio paths to absolute via
  Path.resolve() before passing to ffmpeg/ffprobe (which don't honor
  `--` as end-of-options), so a relative path starting with `-` can
  never be misinterpreted as a flag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
bradautomates
2026-05-09 08:13:32 +10:00
parent 755c157466
commit 3c488688d1
3 changed files with 8 additions and 5 deletions
+4 -1
View File
@@ -18,8 +18,10 @@ VIDEO_EXTS = {".mp4", ".mkv", ".webm", ".mov", ".m4v", ".avi", ".flv", ".wmv"}
def is_url(source: str) -> bool: def is_url(source: str) -> bool:
if source.startswith("-"):
return False
parsed = urlparse(source) parsed = urlparse(source)
return parsed.scheme in ("http", "https") return parsed.scheme in ("http", "https") and bool(parsed.netloc)
def resolve_local(path: str) -> dict: def resolve_local(path: str) -> dict:
@@ -78,6 +80,7 @@ def download_url(url: str, out_dir: Path) -> dict:
"--no-playlist", "--no-playlist",
"--ignore-errors", "--ignore-errors",
"-o", output_template, "-o", output_template,
"--",
url, url,
] ]
+2 -2
View File
@@ -66,7 +66,7 @@ def get_metadata(video_path: str) -> dict:
"-print_format", "json", "-print_format", "json",
"-show_format", "-show_format",
"-show_streams", "-show_streams",
video_path, str(Path(video_path).resolve()),
], ],
capture_output=True, capture_output=True,
text=True, text=True,
@@ -162,7 +162,7 @@ def extract(
cmd += ["-to", f"{end_seconds:.3f}"] cmd += ["-to", f"{end_seconds:.3f}"]
cmd += [ cmd += [
"-i", video_path, "-i", str(Path(video_path).resolve()),
"-vf", f"fps={fps},scale={resolution}:-2", "-vf", f"fps={fps},scale={resolution}:-2",
"-frames:v", str(max_frames), "-frames:v", str(max_frames),
"-q:v", "4", "-q:v", "4",
+2 -2
View File
@@ -93,13 +93,13 @@ def extract_audio(video_path: str, out_path: Path) -> Path:
"-hide_banner", "-hide_banner",
"-loglevel", "error", "-loglevel", "error",
"-y", "-y",
"-i", video_path, "-i", str(Path(video_path).resolve()),
"-vn", "-vn",
"-acodec", "libmp3lame", "-acodec", "libmp3lame",
"-ar", "16000", "-ar", "16000",
"-ac", "1", "-ac", "1",
"-b:a", "64k", "-b:a", "64k",
str(out_path), str(out_path.resolve()),
] ]
result = subprocess.run(cmd, capture_output=True, text=True) result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0: if result.returncode != 0: