T09 · Insecure Skill Coding Practices
- Location
scripts/frame.sh:62- Finding
Unvalidated Frame Index Permits FFmpeg Filtergraph Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/frame.sh, lines 29-31 and 62-65
Vulnerability Type: FFmpeg filtergraph injection through unvalidated input
Risk Level: MediumVulnerable Code
bash --index) index="${2:-}" shift 2 ;;bash if [[ "$index" != "" ]]; then ffmpeg -hide_banner -loglevel error -y \ -i "$in" \ -vf "select=eq(n\\,${index})" \ -vframes 1 \ "$out"Technical Analysis
The value supplied through
--indexis copied intoindexwithout validating that it is a non-negative integer. It is then interpolated directly into the argument passed to FFmpeg's-vfoption.Shell quoting prevents the value from being interpreted as shell syntax, so this is not direct shell-command injection. However, the quoted value is still parsed by FFmpeg as filtergraph syntax. An attacker can supply FFmpeg expression delimiters, commas, parentheses, option assignments, or additional filter names rather than an integer. By balancing the final parenthesis appended by the script, a crafted value can modify the intended
selectexpression or append filters supported by the installed FFmpeg build.Attack Path
- An attacker gains control of the value passed to
frame.sh --index, such as through an agent-generated invocation based on untrusted user input. - The script accepts the value without checking its format.
- The value is inserted into
select=eq(n\,${index}). - FFmpeg parses the resulting string as a filtergraph rather than treating the entire value as an integer.
- Injected filters execute inside the FFmpeg process with the permissions and resource access of the user running the Skill.
For example, a value structured like
0),FILTER=EXPRESSION(can close the intended expression and introduce another filter while using the script's final parenthesis to complete the injected syntax. The exact usable filters and gramma ...[truncated 642 chars]- An attacker gains control of the value passed to
- Remediation
View remediation
Remediation Suggestions
Validate
--indexbefore constructing the FFmpeg filter and reject every value that is not composed exclusively of decimal digits:bash if [[ -n "$index" && ! "$index" =~ ^[0-9]+$ ]]; then echo "Invalid --index: expected a non-negative integer" >&2 exit 2 fiApply the validation immediately after argument parsing and before creating directories or invoking FFmpeg. Consider additionally enforcing a reasonable maximum index to limit unexpectedly expensive decoding:
bash max_index=1000000 if [[ -n "$index" ]]; then if [[ ! "$index" =~ ^[0-9]+$ ]] || (( 10#$index > max_index )); then echo "Invalid --index: expected an integer from 0 to $max_index" >&2 exit 2 fi fiThe security boundary must be syntactic validation rather than shell quoting, because FFmpeg independently parses the
-vfargument after shell processing. Add regression tests covering letters, negative values, commas, parentheses, backslashes, filter names, empty values, and excessively large integers.
