T09 · Insecure Skill Coding Practices
- Location
scripts/extract-frames.sh:16- Finding
Unvalidated FPS Argument Allows FFmpeg Filtergraph Injection
- Content
View full analysis
&1 | grep -E "Duration|Input #|Stream #.*Video" # Extract frames # Output as JPEG with quality 2, scaled to max width 1280px ffmpeg -y -i "$VIDEO_FILE" -vf "fps=$FPS,scale='min(1280,iw)':-2" -q:v 2 "$OUT_DIR/frame%04d.jpg" ``` ### Technical Analysis The optional `FPS` argument is inserted directly into an FFmpeg filtergraph: ```bash -vf "fps=$FPS,scale=..." ``` Shell quoting prevents ordinary shell command substitution at this stage, but it does not make the value safe for FFmpeg's filtergraph parser. FFmpeg treats commas, semicolons, brackets, and filter options as filtergraph syntax. Consequently, an attacker-controlled value can terminate the intended `fps` expression and append additional video filters. For example, an argument conceptually shaped like the following can append a `drawtext` filter where supported: ```text 1,drawtext=textfile=/etc/passwd ``` FFmpeg would interpret this as an `fps` filter followed by an additional filter that reads a local text file and renders its contents into generated frames. The exact payload may require filter-specific escaping or options depending on the installed FFmpeg build. Other available filters could be abused to alter output unexpectedly, access local or remote resources, or impose excessive CPU, memory, disk, or frame-generation costs. The vulnerability exists because the script accepts unrestricted filtergraph syntax where it expects only a positive numeric frame rate. ### Attack Path 1. An attacker supplies or influences the optional third argument passed to `scripts/extract-frames.sh`. 2. ...[truncated 1487 chars]- Remediation
View remediation
&2 exit 1 fi ``` Also enforce a conservative upper bound to limit CPU, memory, and disk consumption. Integer-based validation is preferable if fractional rates are not required: ```bash FPS="${3:-1}" if ! [[ "$FPS" =~ ^[1-9][0-9]*$ ]] || (( FPS > 30 )); then echo "Error: FPS must be an integer between 1 and 30." >&2 exit 1 fi ``` Additional hardening measures should include: 1. Run FFmpeg under a dedicated, least-privileged account with access only to required input and output paths. 2. Apply execution time, memory, CPU, file-size, and process limits. 3. Restrict outbound network access for the FFmpeg process when network access is unnecessary. 4. Store outputs in a controlled directory and verify that generated files remain within that directory. 5. Treat every value inserted into an FFmpeg filtergraph as parser-sensitive input, even when shell quoting is correctly used. ]]>
