Back to skill

Security audit

Youtube Subtitle Burner

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly purpose-aligned for downloading videos and burning subtitles, but its setup normalizes running an unverified remote installer and unpinned runtime dependency.

Review and replace the `curl | sh` uv installation step before installing, preferably with a trusted package-manager install or a pinned verified artifact. Run the workflow in a limited working directory, inspect the proxy-switch command before use, and pin Pillow or use a locked environment for reproducible execution.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:25
Finding

Unverified Remote Installer Executed Through a Shell Pipeline

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:21-26; the same unsafe command is repeated as an installation requirement in scripts/burn_subtitles.py:24-28
Vulnerability Type: Remote payload retrieval and execution
Risk Level: Critical

Complete Code Snippet:

bash
# macOS
brew install ffmpeg yt-dlp

# uv (Python environment management, automatically handles dependencies)
curl -LsSf https://astral.sh/uv/install.sh | sh

The renderer documentation repeats the command:

python
Requirements:
    - ffmpeg/ffprobe installed (brew install ffmpeg)
    - uv installed (curl -LsSf https://astral.sh/uv/install.sh | sh)
    - macOS font: /System/Library/Fonts/STHeiti Medium.ttc

Technical Analysis

The installation instructions retrieve shell code from a mutable external URL and immediately execute it using sh. The downloaded content is not pinned to a reviewed release and is not verified using a cryptographic hash or signature. HTTPS protects the connection in transit, but it does not ensure that the server, DNS resolution, certificate trust chain, or remotely hosted installer remains uncompromised.

Because the response is never saved for inspection, users cannot verify which commands will execute. The effective payload may also change after the Skill package has been audited. Installing uv is ancillary environment setup and does not require piping unverified network content directly into a shell, so this behavior exceeds the minimum execution exposure necessary for subtitle processing.

Attack Path

  1. A user follows the setup instructions and runs the documented command.
  2. curl connects to https://astral.sh/uv/install.sh and retrieves the installer content available at that moment.
  3. A compromise of the distribution server, DNS or certificate trust path, or published installer causes attacker-controlled shell commands to be returned.
  4. The pipe passes that content di ...[truncated 903 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove all curl | sh installation instructions, including the copy in the renderer's documentation.
  2. Prefer a trusted operating-system package manager with a version-pinned package:
    bash
    brew install uv
    
  3. If direct artifact installation is necessary, pin an exact release rather than using a mutable installer endpoint.
  4. Download the release artifact to disk, verify its publisher-provided cryptographic signature or SHA-256 checksum, and only then install it.
  5. Document the expected artifact version, source URL, checksum, and verification commands.
  6. Run installation without administrator privileges unless the selected installation method strictly requires elevation.
  7. Keep installation separate from Skill execution so users can review and approve environment changes before processing any media.

T08 · Insecure Dependencies

Warning
Location
scripts/burn_subtitles.py:4
Finding

Unpinned Pillow Dependency Is Automatically Resolved at Runtime

Content
View full analysis

Vulnerability Details

File Location: scripts/burn_subtitles.py:4-6
Vulnerability Type: Insecure third-party dependency resolution
Risk Level: Medium

Complete Code Snippet:

python
# dependencies = [
#     "pillow",
# ]

SKILL.md additionally states that uv run automatically creates an environment and installs the declared dependencies.

Technical Analysis

The PEP 723 dependency declaration specifies only the package name pillow. It provides no exact version, lockfile, artifact hash, or signature requirement. Consequently, uv run may resolve a different package release over time even though the audited Skill source remains unchanged.

Automatic installation is necessary to provide Pillow's image-rendering functionality, but unconstrained resolution is not necessary. A reviewed exact version can provide the same functionality with substantially better reproducibility and supply-chain control.

This finding does not establish that the legitimate Pillow package is currently malicious. The risk is that future package compromise, repository compromise, malicious artifact substitution, or an unexpectedly incompatible release could introduce code that was not included in this audit.

Attack Path

  1. A user invokes the renderer through uv run.
  2. uv reads the inline dependency declaration and resolves the currently available pillow release satisfying the unconstrained requirement.
  3. The package and any applicable installation artifacts are retrieved from the configured package index.
  4. If the selected artifact, package release, account, or package index has been compromised, unreviewed code is installed into the generated environment.
  5. That code executes when the renderer imports Pillow:
    python
    from PIL import Image, ImageDraw, ImageFont
    
  6. The malicious dependency code then runs with the privileges of the user processing the video.

Impact Assess

...[truncated 501 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin Pillow to an exact, reviewed release in the inline metadata:
    python
    # dependencies = [
    #     "pillow==REVIEWED_VERSION",
    # ]
    
  2. Generate and commit a lockfile that records the complete resolved dependency graph.
  3. Enforce cryptographic hashes for downloaded distributions where supported.
  4. Prefer prebuilt artifacts from the official package source and restrict installation to a trusted package index.
  5. Review and deliberately update the pinned version rather than resolving the newest release during ordinary Skill execution.
  6. Run media processing in an isolated, non-privileged environment with access limited to the required input and output paths.
  7. Add automated dependency vulnerability and provenance checks to the release process.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The supplied code is narrowly focused on subtitle burn-in for an already existing video plus subtitle JSON. It uses ffprobe/ffmpeg and PIL to decode frames, render subtitle text with a yellow rounded box, optionally apply 2x supersampling antialiasing, and encode an H.264/AAC MP4. This does align with the subtitle-rendering portion of the description, including portrait handling and MP4 output. However, the declared purpose claims a broader pipeline: downloading YouTube videos, extracting word-level timing, and translating to Chinese. None of those capabilities appear in this code chunk. Because major declared functions are absent and the actual code only implements one stage of the described workflow, the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full video-download, translation, subtitle-rendering, and MP4-generation workflow. In contrast, the supplied code chunk is a narrow subtitle preprocessing utility. It reads an existing json3 subtitle file from disk, extracts word timestamps, removes duplicates from rolling cues, groups words into timed segments, and saves those segments as JSON. While this partially aligns with the 'extract word-level timeline' portion of the description, it does not implement the core advertised behavior around downloading videos, translating to Chinese, rendering subtitles with PIL, anti-aliasing, handling video formats/orientations, or producing a subtitled MP4. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description describes a full end-to-end video pipeline. The supplied code only handles a narrow subtitle-translation preparation step: loading subtitle segments from JSON, formatting them into translation batches, optionally printing them, and writing a template output file. There is no code for accessing YouTube, downloading media, extracting audio/transcripts, generating word-level timing, using PIL, compositing subtitles onto frames, handling video orientation, or encoding/exporting MP4. The only overlap is subtitle translation support, and even that is incomplete because this script does not actually call an LLM API—it mainly formats data for manual or agent-based translation. Therefore the code materially differs from the declared primary purpose.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The | sh construct is a classic command-chaining anti-pattern because it converts remote content retrieval directly into code execution. This eliminates any review boundary and magnifies supply-chain, man-in-the-middle, or compromised-host risks into full shell execution on the local machine. In a skill-installation context, users are especially likely to trust and copy-paste it, increasing practical exploitability.

Content

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

brew install ffmpeg yt-dlp

uv(Python 环境管理,自动处理依赖)

curl -LsSf https://astral.sh/uv/install.sh | sh

text

Python 脚本使用 PEP 723 内联依赖声明(`# /// script`),`uv run` 会自动创建虚拟环境并安装依赖(如 Pillow),用户无需手动管理 Python 环境。

Lp1

High
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill has shell/process-execution capability via ffmpeg and ffprobe, but that capability is not declared in permissions. In an agent-skill context, undeclared execution capability is dangerous because it can bypass operator expectations and enable processing of attacker-supplied files through powerful native binaries.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'file_write' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The summary and description state that subtitles are translated into Chinese and burned into the video, presenting Chinese output as the fixed behavior. This is a natural-language locale policy concern because the skill forces a specific language without documenting user opt-in or offering alternatives.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

The skill instructs the user to send a state-changing HTTP request over a local Unix socket to a Clash/Mihomo control API to switch proxy nodes. Even though the destination is localhost, it modifies network-routing behavior and could redirect future traffic through an unintended proxy if reused blindly or adapted maliciously. In this skill context it is somewhat less dangerous because the command is presented as operational troubleshooting, but it still performs an external control action against another local service.

Content

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

代理不通时用 Clash unix socket 切换节点:

bash
curl -s --unix-socket /tmp/verge/verge-mihomo.sock \
  -X PUT 'http://localhost/proxies/%F0%9F%93%B9%20YouTube' \
  -H "Content-Type: application/json" \
  -d '{"name":"⚡ 最快线路"}'

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

python
def probe_video(video_path):
    """Get video dimensions and duration using ffprobe."""
    probe = subprocess.run(
        ["ffprobe", "-v", "error", "-select_streams", "v:0",
         "-show_entries", "stream=width,height,duration", "-of", "csv=p=0", video_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/burn_subtitles.py (reported line 169)May include surrounding context.

python
else:
        decode_cmd = ["ffmpeg", "-i", video_in, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"]

    decode_pipe = subprocess.Popen(
        decode_cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.DEVNULL

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

python
encode_cmd.insert(-1, "-t")
        encode_cmd.insert(-1, str(preview_sec))

    encode_pipe = subprocess.Popen(
        encode_cmd,
        stdin=subprocess.PIPE,
        stderr=subprocess.DEVNULL

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring and CLI description present this file as a translator that outputs segments with 'text_zh' added, and the usage example implies standalone translation. In reality, the code never invokes any LLM or performs translation; it only prints batches or writes output objects with empty 'text_zh' fields.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The docstring states that the script 'outputs segments with text_zh field added,' which implies translated content is produced. However, lines L123-L135 generate a template where 'text_zh' is always an empty string, directly contradicting the documented behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file describes downloading YouTube videos and producing local MP4 outputs, which affects user data and disk state, but it does not provide an explicit up-front warning about local file creation/storage impact. Although later sections show commands and mention disk usage for raw intermediates, the description itself lacks a concise user-facing warning about local downloads and output file writes.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Piping a fetched installer script directly from the network into a shell executes unreviewed remote code with the user's privileges. If the remote host, transport, DNS, or distribution channel is compromised, this becomes an immediate arbitrary-code-execution path. The skill context makes this more dangerous because it normalizes a one-line install pattern in setup instructions, encouraging users to execute it without inspection.

Content

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

brew install ffmpeg yt-dlp

uv(Python 环境管理,自动处理依赖)

curl -LsSf https://astral.sh/uv/install.sh | sh

text

Python 脚本使用 PEP 723 内联依赖声明(`# /// script`),`uv run` 会自动创建虚拟环境并安装依赖(如 Pillow),用户无需手动管理 Python 环境。

External Script Fetching

Low
Category
Supply Chain
Confidence
15% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

python
Requirements:
    - ffmpeg/ffprobe installed (brew install ffmpeg)
    - uv installed (curl -LsSf https://astral.sh/uv/install.sh | sh)
    - macOS font: /System/Library/Fonts/STHeiti Medium.ttc
"""
import argparse

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The translate_with_agent docstring suggests a translation-oriented function that prepares batches for LLM processing. The actual implementation simply prints timing and source text to stdout and returns nothing, so the documented behavior overstates what the function does.

Content

No source excerpt is available for this finding.