Back to skill

Security audit

AI视频短视频创作器

Security checks for vulnerabilities and agentic risk

Overview

This video-making skill is mostly aligned with its purpose, but its scripts can run unintended local commands through unsafe config and FFmpeg handling.

Review before installing. Only run config.py files you trust, avoid untrusted or unusual path and segment names, and prefer running the scripts in an isolated project environment. Pin dependencies where possible, and do not send sensitive or unpublished narration text through edge-tts unless you are comfortable with that external TTS data flow.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/step2_edit_video.py:108
Finding

Shell Command Injection in FFmpeg Transition Assembly

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:18
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation
" ``` 2. Maintain dependencies in a lock or requirements file containing hashes: ```text edge-tts== \ --hash=sha256: ``` Install it with: ```bash python -m pip install --require-hashes -r requirements.txt ``` 3. Pin and hash all transitive dependencies, preferably through a reproducible lock-file workflow. 4. Use the official Python package index or an organization-controlled mirror rather than an arbitrary user-configured source. 5. Review dependency release notes and artifacts before updating the pinned version. 6. Run installation and media processing in a virtual environment or isolated container with only the workspace permissions required. 7. Update both `SKILL.md` and `README.md` so they provide the same hardened installation procedure. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This is a substantive behavior mismatch because the declared skill describes a constrained media workflow, but the referenced implementation reportedly imports and executes a local Python config via importlib. Loading attacker-controlled local config as code can lead to arbitrary code execution during a seemingly harmless content-preparation step, and writing outside a clearly bounded output path further increases the risk of unintended file modification.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

xfade_concat builds a shell command string from clip_paths and output_path, then executes it with os.system. Because those values can derive from config, workspace paths, or filenames, an attacker who controls a path containing shell metacharacters or quotes could break out of the intended command and execute arbitrary OS commands.

Content

Scanner excerpt · scripts/step2_edit_video.py (reported line 136)May include surrounding context.

python
cmd = cmd.replace(f"OFFSET{i}", f"{offset_val:.2f}")

    print(f"    xfade chain: {n} clips, {n-1} transitions")
    ret = os.system(cmd)
    if ret != 0:
        print("    xfade failed -> fallback to simple concat")
        return concat_simple(clip_paths, output_path, output_dir)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README specifies a Chinese default voice and only lists Chinese voice options, while the document itself presents the tool as generally suitable for social-media video creation rather than clearly limiting it to a Chinese-only use case. This can violate language/locale policy because it imposes a specific locale without user opt-in or an explicit documented constraint.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs use of shell, file reads, and file writes but does not declare any tool scope or permissions boundaries. That omission weakens reviewability and least-privilege controls, making it easier for an agent/runtime to grant broader capabilities than the task actually needs, especially given direct execution of Python and FFmpeg workflows against user-supplied paths.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The instructions set the default voice to zh-CN-YunxiNeural and elsewhere assume Chinese subtitle rendering via SimHei, which imposes a specific locale/language preference. The policy allows locale constraints when users are given a choice or the constraint is clearly justified as region-specific; this file does not clearly offer such an opt-in language selection as part of the skill's general behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script sends narration text to edge-tts, which involves transmitting user-provided content to an external service, but it does so without explicit disclosure or consent in the script flow. In a video-production context this may be expected, yet it still creates privacy and confidentiality risk if scripts contain sensitive or unpublished material.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script dynamically loads and executes a user-supplied Python config file with spec.loader.exec_module(cfg), which grants arbitrary code execution at startup. That is much broader than needed for configuration of paths and segment metadata, and an attacker who can influence the config file or its path can run code on the host under the script's privileges.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Beyond the core code-execution issue, the script does not clearly disclose to users that providing a config.py will execute arbitrary Python code. This increases risk because users may reasonably treat a config file as inert data, making social engineering or supply-chain abuse of shared project configs more likely.

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/step1_generate_review.py (reported line 38)May include surrounding context.

python
def get_duration(path):
    r = subprocess.run(
        ["ffprobe", "-v", "error", "-show_entries", "format=duration",
         "-of", "default=noprint_wrappers=1:nokey=1", str(path)],
        capture_output=True, text=True

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/step2_edit_video.py (reported line 33)May include surrounding context.

python
def get_duration(path):
    r = subprocess.run(
        ["ffprobe", "-v", "error", "-show_entries", "format=duration",
         "-of", "default=noprint_wrappers=1:nokey=1", str(path)],
        capture_output=True, text=True

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/step1_generate_review.py (reported line 52)May include surrounding context.

python
def get_resolution(path):
    r = subprocess.run(
        ["ffprobe", "-v", "error", "-select_streams", "v:0",
         "-show_entries", "stream=width,height",
         "-of", "default=noprint_wrappers=1", str(path)],

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/step2_edit_video.py (reported line 45)May include surrounding context.

python
def get_resolution(path):
    r = subprocess.run(
        ["ffprobe", "-v", "error", "-select_streams", "v:0",
         "-show_entries", "stream=width,height",
         "-of", "default=noprint_wrappers=1", str(path)],

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/step2_edit_video.py (reported line 65)May include surrounding context.

python
def ffmpeg_run(args):
    """Run ffmpeg command with args list (no shell escaping issues)."""
    cmd = ["ffmpeg", "-y"] + args
    r = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace')
    if r.returncode != 0:
        print(f"    FFmpeg error: {(r.stderr or '')[-300:]}")
    return r.returncode == 0

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code comments and docstrings claim FFmpeg is invoked without shell escaping issues, but xfade_concat contradicts that by constructing a shell command and using os.system. This mismatch is dangerous because reviewers may trust the safety claim and overlook the command-injection surface created by the shell-executed path handling.

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/step2_edit_video.py (reported line 194)May include surrounding context.

python
"-c:v", "libx264", "-preset", "fast", "-crf", "20",
           "-pix_fmt", "yuv420p", output_path]

    result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8", errors="replace")
    if result.returncode != 0:
        print(f"    FFmpeg error: {(result.stderr or '')[-500:]}")
        shutil.copy2(input_path, output_path)

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/step2_edit_video.py (reported line 209)May include surrounding context.

python
cmd2 = ["ffmpeg", "-y", "-i", input_path, "-vf", vf2,
                    "-c:v", "libx264", "-preset", "fast", "-crf", "20",
                    "-pix_fmt", "yuv420p", output_path]
            result2 = subprocess.run(cmd2, capture_output=True, text=True, encoding="utf-8", errors="replace")
            out_size2 = os.path.getsize(output_path)
            ok = out_size2 != in_size
            if ok:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code defaults VOICE to "zh-CN-YunxiNeural", which hard-codes a Chinese locale for narration generation when the config does not override it. This imposes a language/locale choice on users without offering selection or documenting an opt-in, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The config sets VOICE = "zh-CN-YunxiNeural", which forces a Chinese locale by default. The surrounding comments list only Chinese voices and do not mention that users may choose another language/locale or why Chinese is required, which is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The module documentation states that OUTPUT_DIR is the path to the output folder, implying generated artifacts are placed there, and the script description says it exports subtitle_review.md as part of step output. However, the actual write target is review_path = VIDEO_DIR / "subtitle_review.md", which places the generated review artifact alongside source videos instead of the output directory.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This docstring explicitly states the script's approach is to use subprocess without a shell to avoid Windows escaping problems entirely. However, later/elsewhere in the same script, xfade_concat executes FFmpeg through os.system with a composed shell command, so the documented claim of avoiding shell execution entirely is not true for the script's actual behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.