Back to skill

Security audit

AI Video Clip Assistant

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local video-editing assistant, but AI-influenced edit files can drive FFmpeg with unchecked file paths, so it needs careful review before installation.

Install only if you are comfortable running local FFmpeg and ML transcription tools on chosen media files. Review every generated EDL before rendering, reject unexpected source or subtitle paths, avoid rendering EDLs from untrusted transcripts, and prefer an isolated virtual environment with pinned dependencies.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
scripts/generate_edl.py:133
Finding

Untrusted transcript content can influence unvalidated FFmpeg rendering instructions

Content
View full analysis
str: """Build the prompt sent to the LLM.""" ``` The resulting transcript is inserted directly into the prompt: ```python prompt = template.format( transcript_text=transcript_text, **merged, custom_prompt=params.get("custom_prompt", "无特殊要求"), ) ``` `scripts/render_edl.py:191-225`: ```python for i, edit in enumerate(edits): edit_type = edit.get("type", "keep") if edit_type not in ("keep",): print(f" [{i+1}/{len(edits)}] 跳过 {edit_type} (暂不支持)") continue source_id = edit.get("source", edit.get("source_id", "src0")) src_info = sources.get(source_id, {}) src_path = src_info.get("path", "") start = edit.get("start", 0) end = edit.get("end", 0) reason = edit.get("reason", "") params = edit.get("params", {}) if not src_path or end <= start: continue seg_file = os.path.join(tmp_dir, f"seg_{i:04d}.mp4") print(f" [{i+1}/{len(edits)}] {start:.1f}s-{end:.1f}s ({end - start:.1f}s)" f" — {reason[:50]}") if not extract_segment(src_path, start, end, seg_file): continue current = seg_file if params.get("color_grade"): graded = os.path.join(tmp_dir, f"seg_{i:04d}_graded.mp4") ...[truncated 4326 chars]
Remediation
View remediation
start`, maximum segment lengths, and source-duration bounds. - Add `srt_path` to the schema only with explicit validation if it is intended to be supported. 3. Restrict source paths: - Resolve paths with `Path.resolve()`. - Require source and subtitle files to remain inside user-approved directories. - Reject URL schemes and FFmpeg pseudo-protocols unless the user explicitly authorizes them. - Consider invoking FFmpeg with a restrictive `-protocol_whitelist` appropriate to local processing. 4. Secure FFmpeg filter construction: - Escape path and style values according to FFmpeg filtergraph rules. - Avoid direct string interpolation into filter expressions. - Allowlist fonts, colors, positions, and other style fields. 5. Enforce approval at the trust boundary: - Display source-path and subtitle-path changes prominently. - Require explicit confirmation before rendering EDLs produced by an LLM. - Do not rely solely on workflow documentation for approval. 6. Add resource controls: - Apply subprocess timeouts and file-size, duration, resolution, and output-size limits. - Run FFmpeg with reduced privileges and constrained network access when processing untrusted media. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:282
Finding

Unpinned third-party dependency installation creates supply-chain exposure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (46)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad AI video editing assistant with speech recognition, semantic understanding, LLM-based decision-making, subtitles, highlight extraction, rendering, and export adaptation. The supplied code only performs deterministic video cutting using FFmpeg based on user-supplied timestamps or an existing EDL file. While EDL input loosely aligns with '剪辑决策(EDL)', the code does not generate those decisions or use any AI/LLM capability. Its actual scope is a narrow subset of the description, so the description materially overstates the behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个功能全面的 AI 视频剪辑助手,而代码片段的实际范围明显更窄,只是一个“高光片段提取”脚本。它依赖 FFmpeg/ffprobe 做场景与音频分析,并可利用外部已存在的 transcript JSON 做简单计数式语义评分,但并不执行语音识别,也没有词级时间戳、LLM 决策、EDL 生成、字幕烧录、自检循环或多平台导出逻辑。虽然“提取高光片段”属于声明中的一部分使用场景,但声明将技能描述为更完整、更智能、更端到端的视频编辑系统,和该代码片段实际能力不符,属于描述显著宽于实际行为的情况。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个功能完整的视频剪辑助手,而当前代码片段的实际作用非常有限:它将 transcript 转为文本、根据预设模板构建剪辑 prompt、校验/构造 EDL 结构,并在默认模式下只写出一个空 edits 的 EDL 模板。即使包含 validate_edl 等辅助函数,也没有在主流程中真正生成或验证来自 LLM 的 EDL。代码中提到 render_edl.py 和“将 prompt 发送给 LLM”说明实际关键能力依赖外部步骤或其他脚本,当前片段并未实现。虽然代码内容与“LLM 驱动剪辑决策(EDL)”这一子能力相关,但仅是前置准备工具,远不足以支撑声明中的主要能力范围,因此存在明显描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad AI video editing assistant covering automated editing, semantic understanding for clip selection, EDL generation, rendering, export, and subtitle burn-in. The supplied code only implements one subset capability: ASR-based subtitle generation to SRT using Whisper, with different subtitle segmentation modes. It does not perform video editing, clipping, rendering, LLM reasoning, highlight extraction, platform adaptation, or subtitle burn-in. While subtitle generation is consistent with part of the description, the actual code’s primary purpose is much narrower than the declared skill purpose, so the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad AI video editing assistant with transcription, semantic understanding, LLM-based decision-making, subtitle generation, highlight extraction, and export adaptation. The supplied code does not implement those AI or upstream editing capabilities. Instead, it only performs downstream rendering from an existing EDL: extracting 'keep' segments, optionally color grading and burning provided subtitles, and concatenating outputs via FFmpeg. This is materially narrower than the declared purpose. While 'video rendering' and subtitle burn-in are consistent with the description, the overall declared capability set is significantly broader than what this code chunk actually does. Therefore this chunk does not accurately represent the full declared description on its own.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/generate_edl.py (reported line 180)May include surrounding context.

python
custom_prompt=params.get("custom_prompt", "无特殊要求"),
    )

    return prompt


def validate_edl(edl: dict, transcript: dict) -> tuple:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises and documents shell execution, file read/write, and environment-dependent behavior, but it declares no explicit tool scope or permission boundaries. In an agent environment, that can lead to overbroad access at runtime and make it easier for the skill to invoke powerful local operations on arbitrary user-supplied paths.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation guidance is broad enough that the agent may invoke this skill for many loosely related video tasks, increasing the chance of unnecessary shell/file operations on user content. In a skill that appears to depend on local scripts, FFmpeg, and arbitrary filesystem paths, overbroad routing expands the exposure surface and can lead to unintended processing of sensitive media.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The natural-language content, headings, and comments in this skill file are all presented in Chinese, and the file does not offer the user an alternative language or state that the skill is intentionally region- or locale-specific. Per the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains user-facing natural-language strings such as the module docstring, argument descriptions, status output, and error messages entirely in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code's natural-language surface is consistently Chinese, including the module description, help text, and runtime status/error messages. Under the language/locale policy, forcing a specific language without opt-in is a policy issue unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/export_social.py (reported line 21)May include surrounding context.

python
"-c:a", "aac",
        output
    ]
    return subprocess.run(cmd, capture_output=True).returncode == 0

def scale_and_pad(input_file: str, target_size: str, output: str) -> bool:
    """缩放并填充黑边以适应目标比例。"""

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/extract_highlights.py (reported line 109)May include surrounding context.

python
"-c:a", "aac",
        output
    ]
    return subprocess.run(cmd, capture_output=True).returncode == 0

def scale_and_pad(input_file: str, target_size: str, output: str) -> bool:
    """缩放并填充黑边以适应目标比例。"""

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/transcribe.py (reported line 60)May include surrounding context.

python
"-c:a", "aac",
        output
    ]
    return subprocess.run(cmd, capture_output=True).returncode == 0

def scale_and_pad(input_file: str, target_size: str, output: str) -> bool:
    """缩放并填充黑边以适应目标比例。"""

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/export_social.py (reported line 34)May include surrounding context.

python
"-c:a", "aac",
        output
    ]
    return subprocess.run(cmd, capture_output=True, text=True).returncode == 0

def export(input_file: str, fmt: str, duration: float, output_dir: str) -> list:
    os.makedirs(output_dir, exist_ok=True)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code file contains natural-language strings such as the module docstring, argparse description/help text, and runtime print messages entirely in Chinese. The policy calls for flagging language or locale constraints when the skill forces a specific language without user opt-in, and there is no alternative locale selection or justification in the file.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/burn_subtitles.py (reported line 76)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/burn_subtitles.py (reported line 87)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cut_video.py (reported line 17)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/extract_highlights.py (reported line 12)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/extract_highlights.py (reported line 53)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/render_edl.py (reported line 27)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/render_edl.py (reported line 38)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/self_eval.py (reported line 28)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/self_eval.py (reported line 42)May include surrounding context.

python
"ffprobe", "-v", "quiet", "-print_format", "json",
        "-show_format", "-show_streams", input_file
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        return {}
    try: