Back to skill

Security audit

Yq Video Motion Analyzer

Security checks for vulnerabilities and agentic risk

Overview

This skill performs disclosed video frame extraction and image-based motion-analysis guidance, with ordinary local file-output risks but no evidence of deception, exfiltration, persistence, or privilege abuse.

Before installing, be aware that the skill writes extracted frames and generated images to disk. Use it only with videos you are comfortable storing locally, prefer the documented output directories, and delete output folders when finished if the media is private.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
script/extract_frames.py:13
Finding

Unrestricted Output Directory Permits Predictable File Overwrites

Content
View full analysis

Vulnerability Details

File Location: script/extract_frames.py, lines 13 and 29–30, with user-controlled input assigned at line 46
Vulnerability Type: Unrestricted filesystem output path and unsafe file overwrite
Risk Level: Medium

Vulnerable Code

python
os.makedirs(output_dir, exist_ok=True)
python
output_path = os.path.join(output_dir, f"frame_{saved_count:04d}_{timestamp:.2f}s.jpg")
cv2.imwrite(output_path, frame)
python
output_dir = sys.argv[2] if len(sys.argv) > 2 else "output/frames"

Technical Analysis

The script accepts output_dir directly from a command-line argument and uses it without path normalization, workspace containment validation, symlink checks, or an allowlist of approved output directories. Although the documented destination is output/frames, the implementation allows any location writable by the executing process.

Frame names are predictable, beginning with frame_0000_0.00s.jpg. OpenCV's cv2.imwrite overwrites an existing file at the selected path without requiring confirmation. Its return value is also ignored, preventing the script from detecting failed or partial writes.

This does not grant permissions beyond those already held by the process, and it does not provide control over arbitrary filenames. However, it permits creation of directories and replacement of matching, predictably named JPEG files outside the intended project output area.

Attack Path

  1. An attacker or untrusted caller supplies a crafted video and sets the second command-line argument to a writable directory outside the intended output root.
  2. The script passes that argument directly to os.makedirs.
  3. If the directory does not exist, the script creates it using the privileges of the running process.
  4. The script constructs predictable names such as frame_0000_0.00s.jpg.
  5. If files with those names already exist in the selected directory, `cv2.imwri ...[truncated 823 chars]
Remediation
View remediation

Remediation Suggestions

  1. Define a trusted output root, such as a project-owned output directory.
  2. Resolve both the trusted root and requested destination with pathlib.Path.resolve().
  3. Reject the destination unless it is equal to or contained beneath the trusted root.
  4. Reject symbolic-link output directories and revalidate containment immediately before each write where concurrent path replacement is a concern.
  5. Refuse to overwrite existing files by default, or generate a unique per-run directory.
  6. Check the Boolean result returned by cv2.imwrite and fail safely when writing does not succeed.
  7. Apply limits to the number and total size of generated frames.

Example containment check:

python
from pathlib import Path

trusted_root = (Path.cwd() / "output").resolve()
requested_dir = Path(output_dir).resolve()

if requested_dir != trusted_root and trusted_root not in requested_dir.parents:
    raise ValueError("Output directory must be inside the approved output root")

requested_dir.mkdir(parents=True, exist_ok=True)

Before writing, check for an existing destination and handle write failures:

python
if output_path.exists():
    raise FileExistsError(f"Refusing to overwrite existing file: {output_path}")

if not cv2.imwrite(str(output_path), frame):
    raise OSError(f"Failed to write frame: {output_path}")

T09 · Insecure Skill Coding Practices

Note
Location
script/extract_frames.py:20
Finding

Missing Interval and Frame-Rate Validation Causes Processing Failure

Content
View full analysis

Vulnerability Details

File Location: script/extract_frames.py, lines 20–26 and 47
Vulnerability Type: Improper numeric input validation resulting in division or modulo by zero
Risk Level: Low

Vulnerable Code

python
fps = cap.get(cv2.CAP_PROP_FPS)
frame_interval = int(fps * interval)

frame_count = 0
saved_count = 0

while True:
    ret, frame = cap.read()
    if not ret:
        break

    if frame_count % frame_interval == 0:
python
interval = float(sys.argv[3]) if len(sys.argv) > 3 else 1.0

Technical Analysis

The command-line interval is converted to a floating-point value without verifying that it is finite and strictly positive. The frame rate returned by OpenCV is also used without verifying that it is finite and greater than zero.

frame_interval is calculated with int(fps * interval). It can therefore become zero under several conditions:

  • The caller supplies 0 as the interval.
  • The caller supplies a negative or sufficiently small interval whose product truncates to zero.
  • A malformed or unusual video causes OpenCV to report an FPS value of zero.
  • A non-finite value is supplied or reported and causes conversion or arithmetic errors.

When frame_interval is zero, the expression frame_count % frame_interval raises ZeroDivisionError, terminating extraction. Negative values may also produce behavior inconsistent with the documented positive time interval.

Attack Path

  1. A caller invokes the script with a zero interval, for example:
    text
    python script/extract_frames.py video.mp4 output/frames 0
    
  2. The script parses the value as 0.0.
  3. frame_interval evaluates to int(fps * 0.0), which is zero.
  4. After the first frame is read, the script evaluates frame_count % 0.
  5. Python raises ZeroDivisionError.
  6. The broad exception handler reports failure and exits with status code 1, preventing frame extrac ...[truncated 642 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require the interval to be a finite, strictly positive number.
  2. Validate that the FPS value returned by OpenCV is finite and greater than zero.
  3. Calculate the frame interval with rounding and enforce a minimum value of one.
  4. Define reasonable upper and lower interval limits to prevent excessive output or ineffective extraction.
  5. Return a clear validation error before entering the frame-processing loop.
  6. Release the video capture object in a finally block or context-management wrapper so resources are cleaned up on every error path.

Example hardening:

python
import math

if not math.isfinite(interval) or interval <= 0:
    raise ValueError("Interval must be a finite number greater than zero")

fps = cap.get(cv2.CAP_PROP_FPS)
if not math.isfinite(fps) or fps <= 0:
    raise ValueError("Video reports an invalid frame rate")

frame_interval = max(1, round(fps * interval))

Consider imposing application-specific limits as well:

python
MIN_INTERVAL = 0.01
MAX_INTERVAL = 3600.0

if not MIN_INTERVAL <= interval <= MAX_INTERVAL:
    raise ValueError("Interval is outside the permitted range")
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

该代码块的行为与声明存在明显不一致。代码通过 OpenCV 打开本地视频文件,按给定秒级间隔抽取帧并保存为 JPEG 图片,属于“截帧/关键帧提取”的子功能。虽然这与声明中的“提取关键帧”部分一致,但声明的核心能力还包括动作姿态分析、火柴人动作示意图生成以及教学改进建议,而这些能力在代码中完全没有体现。因此,该描述夸大了技能能力,不能准确代表当前代码块的实际行为。

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Broad trigger keywords such as common phrases around video or motion analysis can cause the skill to activate unintentionally in unrelated conversations. That increases the chance the agent will process user-provided files or invoke local tooling unexpectedly, which is risky because this skill writes outputs to disk and may operate on user media.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill instructs extraction of video frames and generation of images into local output directories without clearly warning the user that copies of video-derived content will be stored on disk. This can create privacy and data-handling risks, especially if the video contains sensitive personal imagery or if the environment is shared or persistent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring and user-facing descriptions are written only in Chinese, which imposes a specific language on users without any opt-in or alternative locale. The policy explicitly flags language or locale constraints when the skill does not offer a choice or document a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The usage, success, and error messages shown to users are all hard-coded in Chinese, forcing a specific language for interactive output. Because no language selection or clear region-specific justification is present, this is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.