T09 · Insecure Skill Coding Practices
- Location
skill.py:319- Finding
Unsafe Evaluation of FFprobe-Derived Frame-Rate Data
- Content
View full analysis
Vulnerability Details
File Location:
skill.py:319
Vulnerability Type: Python code injection through unrestrictedeval()
Risk Level: HighVulnerable Code:
python "fps": eval(video_stream.get("r_frame_rate", "0/1")) if video_stream else None,Technical Analysis
The
get_video_info()method obtains JSON data from the externalffprobeprocess and passes ther_frame_ratestring directly to Python's unrestrictedeval()function. Although legitimate FFprobe output normally represents frame rates as numeric fractions such as30/1or30000/1001, the code does not validate that the value conforms to this restricted format.eval()interprets its input as a Python expression and executes it in the current process context. Consequently, if the FFprobe output is manipulated to contain a Python expression, that expression can access Python built-ins, import modules, execute operating-system commands, read or alter files, and perform other actions available to the Skill process.A specially crafted media file alone is not proven to make a standard FFprobe installation emit arbitrary Python expressions in
r_frame_rate. Practical exploitation therefore requires a vulnerable or malicious FFprobe build, a spoofed executable earlier inPATH, or another means of manipulating FFprobe's JSON output. Nevertheless, unrestricted evaluation is unnecessary and creates a dangerous execution sink across a process trust boundary.Attack Path
- The attacker gains influence over the
ffprobeexecutable selected fromPATH, its output, or a vulnerable media-parsing path that controls the returnedr_frame_ratevalue. - A user or Agent invokes
VideoTool.get_video_info()on the supplied media file. - The Skill executes
ffprobeand parses its standard output as JSON. - The attacker-controlled expression is retrieved from the video stream's
r_frame_ratefield. - At
skill.py:319,eval()ex ...[truncated 707 chars]
- The attacker gains influence over the
- Remediation
View remediation
Remediation Suggestions
Remove
eval()and parse the frame rate as a constrained rational number:python from fractions import Fraction frame_rate = video_stream.get("r_frame_rate", "0/1") try: numerator, denominator = frame_rate.split("/", 1) if not numerator.isdigit() or not denominator.isdigit(): raise ValueError("Invalid frame-rate format") if int(denominator) == 0: raise ValueError("Frame-rate denominator cannot be zero") fps = float(Fraction(int(numerator), int(denominator))) except (ValueError, ZeroDivisionError): fps = NoneAlternatively, apply a strict regular expression such as
^[0-9]+/[1-9][0-9]*$before usingfractions.Fraction.Additional hardening should include:
- Resolve
ffprobeto a trusted absolute path rather than relying solely on ambientPATH. - Check the FFprobe subprocess return code before parsing its output.
- Reject malformed JSON and unexpected field types.
- Apply reasonable bounds to numerator, denominator, and calculated frame rate.
- Run media parsing with minimal filesystem, environment, and network privileges.
- Keep FFmpeg and FFprobe updated because they process attacker-controlled binary media formats.
- Resolve
