Back to skill

Security audit

Auto Video Editing

Security checks for vulnerabilities and agentic risk

Overview

This is a local video-editing skill with disclosed dependency, media-processing, and network-download behavior, but no evidence of hidden or malicious actions.

Install in a virtual environment, avoid running pip or the skill as an administrator, review any sudo package-manager commands before running them, prefer trusted package indexes with pinned dependencies where possible, and choose output paths carefully because generated media files can overwrite existing files.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:23
Finding

Unpinned Python Dependencies Installed from Mutable Package Indexes

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:23-25, SKILL.md:350, and README.md:63-68
Vulnerability Type: Supply-chain exposure through unpinned dependencies and optional third-party package indexes
Risk Level: Medium

Vulnerable Code

SKILL.md:23-25:

bash
- **whisper**: `pip install faster-whisper`(推荐,速度快 4 倍)或 `pip install openai-whisper`
- **中国用户**加速安装:`pip install faster-whisper -i https://pypi.tuna.tsinghua.edu.cn/simple`

SKILL.md:350:

bash
pip install faster-whisper -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn

README.md:63-68:

bash
pip install faster-whisper  # 推荐,速度快 4 倍
bash
pip install faster-whisper -i https://pypi.tuna.tsinghua.edu.cn/simple

Technical Analysis

The installation instructions do not pin reviewed versions of faster-whisper, openai-whisper, or their transitive dependencies. Each installation can therefore retrieve a different dependency set as upstream packages change.

The Skill also recommends an optional third-party package index. Although the specified mirror uses HTTPS, package integrity is not independently verified through hashes or a lockfile. The --trusted-host recommendation further weakens pip's normal transport validation policy for that host and is unnecessary when correctly configured HTTPS is available.

Python packages can execute code during installation through build backends and can execute additional code when imported. Consequently, compromise of an upstream release, transitive dependency, package index, or mirror could introduce code that was not present during the Skill audit.

Attack Path

  1. An attacker compromises a dependency release, transitive package, publisher account, package index, or recommended mirror.
  2. The attacker publishes or serves a malicious package version under a dependency name expected by the installation.
  3. A user fo ...[truncated 967 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin reviewed direct dependency versions, for example:
    text
    faster-whisper==<reviewed-version>
    
  2. Generate a lockfile that also fixes transitive dependency versions.
  3. Require hashes using a hash-locked requirements file and install with:
    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  4. Prefer the official Python package index unless an organization-controlled, synchronized mirror is required.
  5. Remove --trusted-host; retain normal TLS certificate and hostname validation.
  6. Document the expected package publisher, package digest, and review/update process.
  7. Install dependencies inside a dedicated virtual environment under a non-privileged account.
  8. Test dependency updates separately before changing pinned versions.

T08 · Insecure Dependencies

Warning
Location
scripts/utils.py:300
Finding

Downloaded Font Is Not Verified Before Processing

Content
View full analysis

Vulnerability Details

File Location: scripts/utils.py:300-301 and scripts/utils.py:328-345
Vulnerability Type: Unverified mutable remote component
Risk Level: Medium

Vulnerable Code

scripts/utils.py:300-301:

python
GOOGLE_FONT_URL = "https://github.com/google/fonts/raw/main/ofl/notosanssc/NotoSansSC%5Bwght%5D.ttf"
GOOGLE_FONT_URL_CN = "https://cdn.jsdelivr.net/gh/google/fonts@main/ofl/notosanssc/NotoSansSC%5Bwght%5D.ttf"

scripts/utils.py:328-345:

python
def _download_font(fonts_dir, target_path):
    """Try downloading Noto Sans SC font. Uses CDN mirror for China."""
    urls = []
    if is_china_locale() or os.environ.get("USE_CN_MIRROR"):
        urls.append(GOOGLE_FONT_URL_CN)
    urls.append(GOOGLE_FONT_URL)

    for url in urls:
        try:
            os.makedirs(fonts_dir, exist_ok=True)
            print(f"[font] Downloading Noto Sans SC...")
            req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
            with urllib.request.urlopen(req, timeout=30) as resp:
                with open(target_path, "wb") as f:
                    f.write(resp.read())
            print(f"[font] Downloaded: {target_path}")
            return target_path
        except (urllib.error.URLError, OSError, TimeoutError) as e:
            print(f"[font] Download failed from {url}: {e}")
            continue

Technical Analysis

The Skill automatically downloads a font from GitHub or jsDelivr when a suitable cached font is unavailable. Both URLs reference the mutable main branch. The downloaded response is written directly to the font cache and accepted without checking a cryptographic digest, signature, expected content type, maximum size, or font-file structure.

The downloaded file is later passed to FFmpeg and associated font-processing libraries during subtitle, cover, or chapter rendering. A compromised upstream repository, b ...[truncated 2030 chars]

Remediation
View remediation

Remediation Suggestions

  1. Prefer bundling a reviewed font in the Skill package where licensing permits.
  2. If downloading is necessary, reference an immutable release or commit rather than the mutable main branch.
  3. Hard-code the expected SHA-256 digest and verify it before moving the file into the cache.
  4. Download into a securely created temporary file, validate it, and atomically rename it to the final cache path.
  5. Reject responses exceeding a conservative maximum size.
  6. Validate the response status and optionally its expected media type, while treating content type only as an additional check rather than an integrity control.
  7. Validate that the downloaded object is a supported font before passing it to FFmpeg.
  8. Delete invalid or partially downloaded cache files after any failure.
  9. Consider requiring explicit user consent before the first network download and provide a mode that uses only system or user-supplied fonts.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad automated video-editing toolkit focused on cutting, splitting, merging, audio extraction, transcription, clip selection, and thumbnail generation. The supplied code does not implement those core functions. Instead, its primary purpose is to annotate an existing video with a chapter bar visualization and optional transient chapter labels. While this is related to video post-processing and can consume transcript data, it is a materially different and much narrower capability than the declared editing workflow. The description also omits the chapter-overlay/timeline feature entirely, so the code performs an undeclared capability rather than merely a supporting implementation detail.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · SKILL.md (reported line 362)May include surrounding context.

解决:

bash
sudo apt update && sudo apt install ffmpeg

如果系统源的 ffmpeg 版本过旧(< 4.0),使用 PPA:

bash

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · SKILL.md (reported line 367)May include surrounding context.

解决:

bash
sudo apt update && sudo apt install ffmpeg

如果系统源的 ffmpeg 版本过旧(< 4.0),使用 PPA:

bash

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 52)May include surrounding context.

Ubuntu/Debian/WSL:

bash
sudo apt install ffmpeg fonts-noto-cjk

Windows:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 279)May include surrounding context.

Ubuntu/Debian/WSL:

bash
sudo apt install ffmpeg fonts-noto-cjk

Windows:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 327)May include surrounding context.

Ubuntu/Debian/WSL:

bash
sudo apt install ffmpeg fonts-noto-cjk

Windows:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 362)May include surrounding context.

Ubuntu/Debian/WSL:

bash
sudo apt install ffmpeg fonts-noto-cjk

Windows:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 366)May include surrounding context.

Ubuntu/Debian/WSL:

bash
sudo apt install ffmpeg fonts-noto-cjk

Windows:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 367)May include surrounding context.

Ubuntu/Debian/WSL:

bash
sudo apt install ffmpeg fonts-noto-cjk

Windows:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill explicitly instructs use of shell commands, local file reads/writes, environment inspection, and network access, but it declares no tool scope or permissions boundaries. That creates an unnecessary trust gap: an agent may run broad filesystem or network operations without users being able to see a least-privilege contract up front.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow instruction hard-codes Chinese as the transcription language in the primary example command, which can bias or force operation in a specific locale/language. Although later text mentions other language options, the default execution path shown to the user is Chinese rather than explicitly asking for or auto-detecting the user's preference.

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

python
def _has_drawtext():
    """Check if ffmpeg has drawtext filter."""
    try:
        r = subprocess.run(
            ["ffmpeg", "-hide_banner", "-filters"],
            capture_output=True, text=True, timeout=5
        )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script invokes ffmpeg with -y, which forces overwrite of the destination file without prompting. In an automation skill that processes user-supplied paths, this can destroy existing media or other files at the chosen output location, causing irreversible data loss if the path is incorrect or attacker-influenced.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring states that the script 'Automatically detects language and selects appropriate Chinese/English font,' and the implementation later classifies text only as 'zh' or 'en'. This imposes a fixed language/locale model without offering user choice or documenting that the tool is intentionally limited to those locales.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
78% confidence
Finding

Although subprocess.run is called with an argument list, this code constructs an ffmpeg filter expression from user-influenced paths and transcript-derived subtitle content, then feeds untrusted media into ffmpeg. In a video-editing skill, invoking complex native parsers on attacker-supplied files can expose the host to ffmpeg/codec/parser vulnerabilities or filter-parser edge cases, making this more security-relevant than a generic subprocess call.

Content

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

python
cmd += encode_args + ["-c:a", "copy", output_path]

            subprocess.run(cmd, check=True, capture_output=True, text=True)
            print(f"  clip_{seg_id:03d}.mp4  [{lang}]  {text}")
            success_count += 1
        except subprocess.CalledProcessError as e:

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

python
]

    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"Audio extraction complete: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error extracting audio: {e.stderr}", file=sys.stderr)

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_audio.py (reported line 44)May include surrounding context.

python
]

    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"Audio extraction complete: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error extracting audio: {e.stderr}", file=sys.stderr)

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

python
]

    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"Audio extraction complete: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error extracting audio: {e.stderr}", file=sys.stderr)

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

python
]

    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"Audio extraction complete: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error extracting audio: {e.stderr}", file=sys.stderr)

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

python
]

    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"Audio extraction complete: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error extracting audio: {e.stderr}", file=sys.stderr)

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

python
]

    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"Audio extraction complete: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error extracting audio: {e.stderr}", file=sys.stderr)

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

python
"-of", "json",
        video_path,
    ]
    result = subprocess.check_output(cmd, text=True)
    info = json.loads(result)
    fmt_duration = float(info.get("format", {}).get("duration", 0))
    streams = info.get("streams", [{}])

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 143)May include surrounding context.

python
"-of", "json",
        video_path,
    ]
    result = subprocess.check_output(cmd, text=True)
    info = json.loads(result)
    fmt_duration = float(info.get("format", {}).get("duration", 0))
    streams = info.get("streams", [{}])

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

python
"-of", "json",
        video_path,
    ]
    result = subprocess.check_output(cmd, text=True)
    info = json.loads(result)
    fmt_duration = float(info.get("format", {}).get("duration", 0))
    streams = info.get("streams", [{}])

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

python
"-an",
            cover_clip,
        ]
        subprocess.run(cmd_cover, check=True, capture_output=True, text=True)

        # Step 2: Trim the original video, skip the first frame
        cmd_rest = [

Static analysis

No suspicious patterns detected.