Back to skill

Security audit

Video Transcribe

Security checks for vulnerabilities and agentic risk

Overview

This video transcription skill has a coherent purpose, but its bundled script contains an unsafe code-execution path that needs review before installation.

Review before installing. The skill does what it claims at a high level, but do not pass untrusted prompt text to the bundled script until the python -c source-generation issue is fixed. Prefer removing --no-check-certificates, pinning dependency versions, and keeping video/model cache directories limited to locations you are comfortable storing large downloaded media and model files.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/transcribe.py:64
Finding

Arbitrary Python Code Execution Through Unsafe Source-Code Generation

Content
View full analysis

Vulnerability Details

File Location: scripts/transcribe.py, lines 64–98
Vulnerability Type: Python source-code injection
Risk Level: High

python
cache_dir = WHISPER_CACHE.replace("\\", "/")
video_path_escaped = video_path.replace("\\", "/")

python_code = f"""
import whisper, os, sys, io, time
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
cache_dir = r'{cache_dir}'
os.environ['WHISPER_DOWNLOAD_ROOT'] = cache_dir
print('  加载模型...')
start_load = time.time()
model = whisper.load_model('{model_name}', download_root=cache_dir)
print(f'  模型加载耗时: {{time.time()-start_load:.1f}}秒')
print('  转录中...')
start_trans = time.time()
result = model.transcribe(
    r'{video_path_escaped}',
    language='zh',
    initial_prompt='''{init_prompt}''',
    temperature=0.0,
    condition_on_previous_text=False,
    word_timestamps=False
)
elapsed = time.time() - start_trans
print(f'  转录耗时: {{elapsed:.1f}}秒')
for seg in result['segments']:
    start = seg['start']
    end = seg['end']
    text = seg['text'].strip()
    if text:
        print(f'[{{start:.1f}}s-{{end:.1f}}s] {{text}}')
print('---FULLTEXT---')
print(result['text'])
"""
result = subprocess.run(
    ["python", "-c", python_code],
    capture_output=True, text=True, encoding='utf-8', errors='replace'
)

Technical Analysis

The function constructs executable Python source with an f-string and passes the resulting text to python -c. The optional transcription prompt is assigned to init_prompt and interpolated directly inside a triple-quoted Python string:

python
initial_prompt='''{init_prompt}''',

A prompt containing a triple-quote terminator can escape the intended string literal and introduce arbitrary Python statements into the generated program. Using an argument list for subprocess.run prevents shell expansion, but it does not prevent injection int ...[truncated 1725 chars]

Remediation
View remediation

Remediation Suggestions

Do not generate executable Python source from user-controlled or environment-controlled values.

  1. Import whisper and call whisper.load_model and model.transcribe directly in the current process.
  2. If process isolation is required, move the transcription logic into a fixed, reviewed Python module. Pass the prompt, model name, and paths through normal command-line arguments, JSON over standard input, or another structured data channel.
  3. Validate the model name against the existing strict allowlist in every execution path.
  4. Normalize and validate cache and download directories before use, but do not treat path validation as a substitute for separating code from data.
  5. Avoid eval, exec, python -c, and dynamically generated scripts for transporting user input.
  6. Add regression tests containing triple quotes, newlines, backslashes, quotes, and Python syntax in prompts and paths. Verify that every value remains inert data.
  7. Run media-processing workloads under a dedicated low-privilege account or sandbox to reduce the impact of future code-execution defects.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/transcribe.py:29
Finding

TLS Certificate Verification Disabled for Video Downloads

Content
View full analysis

Vulnerability Details

File Location: scripts/transcribe.py, lines 29–35
Vulnerability Type: Insecure transport configuration
Risk Level: Medium

python
output_path = os.path.join(DOWNLOAD_DIR, "temp_video.%(ext)s")
cmd = [
    "yt-dlp", url,
    "-o", output_path,
    "--no-check-certificates",
    "--no-update"
]

Technical Analysis

The --no-check-certificates option instructs yt-dlp not to validate TLS certificates. This removes server-authentication guarantees for HTTPS connections and allows a network intermediary to present an invalid or forged certificate without the download being rejected.

Because the retrieved content is subsequently processed by media parsers and transcription components, accepting unauthenticated content does more than affect confidentiality or media accuracy. It exposes local yt-dlp, FFmpeg, and Whisper processing paths to content substituted by an active network attacker.

Attack Path

  1. A user invokes the Skill with an HTTPS video URL.
  2. An attacker able to intercept or manipulate network traffic presents a forged certificate or redirects the connection to an attacker-controlled endpoint.
  3. Certificate validation is bypassed because yt-dlp receives --no-check-certificates.
  4. The attacker supplies modified or malicious media content.
  5. The application stores and processes that content using local media and transcription dependencies.
  6. The attacker can corrupt the transcription and downloaded artifact; exploitation of a separate parser defect could potentially lead to code execution.

Impact Assessment

The immediate impact is loss of download integrity and server authenticity. An attacker can substitute media, manipulate generated transcripts, or cause denial of service through malformed or oversized content. If any downstream media component contains an exploitable parsing vulnerability, maliciously substituted content could affec ...[truncated 116 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove --no-check-certificates and use the platform's normal certificate validation.
  2. Repair or update the host certificate trust store if legitimate sites fail validation.
  3. If insecure certificate handling is operationally unavoidable, make it an explicit opt-in setting that is disabled by default and displays a prominent warning.
  4. Restrict accepted URL schemes to HTTPS where supported and reject unexpected local or non-network schemes.
  5. Keep yt-dlp, FFmpeg, and related parsers on reviewed security-supported versions.
  6. Process downloaded media in a sandbox with restricted filesystem access, network access, CPU time, file size, and memory.
  7. Add download-size and duration limits to reduce denial-of-service exposure from untrusted media.

T08 · Insecure Dependencies

Note
Location
SKILL.md:11
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 11–16
Vulnerability Type: Uncontrolled third-party dependency versions
Risk Level: Low

bash
pip install yt-dlp openai-whisper
winget install ffmpeg  # Windows
# brew install ffmpeg  # macOS
# sudo apt install ffmpeg  # Linux

Technical Analysis

The documented installation commands retrieve third-party packages without version constraints, cryptographic hashes, or a dependency lock file. Consequently, the code installed by users can change over time without any corresponding change to the audited Skill package.

The package names do not exhibit an identified typosquatting or dependency-confusion issue, and there is no evidence that the named upstream projects are malicious. The risk arises from non-reproducible installation and reliance on the latest package-manager resolution, including transitive dependencies.

Attack Path

  1. A user follows the installation instructions.
  2. The package manager resolves whatever package versions and transitive dependencies are current at installation time.
  3. An unexpectedly vulnerable, compromised, or behaviorally incompatible upstream release is selected.
  4. Installation hooks or package runtime code execute under the user's account.
  5. The Skill later invokes these dependencies to process attacker-influenced URLs and media.

This is a supply-chain exposure rather than evidence of a presently malicious dependency.

Impact Assessment

Impact depends on the affected dependency. A compromised package or installer could execute code with the installing user's privileges. A vulnerable media-processing release could permit denial of service, data access, or code execution when processing crafted content. The current instructions also reduce build reproducibility and make it difficult to determine which dependency versions were security-reviewed.

Remediation
View remediation

Remediation Suggestions

  1. Pin reviewed versions of direct Python dependencies in a requirements or lock file.
  2. Use hash verification for Python artifacts where practical, such as pip install --require-hashes.
  3. Record and review transitive dependency versions.
  4. Document the expected official repositories and package sources for FFmpeg and Python packages.
  5. Pin or document tested FFmpeg versions for each supported platform.
  6. Automate dependency vulnerability scanning and update pins after security review and compatibility testing.
  7. Build dependencies in an isolated virtual environment rather than installing them globally.
  8. Publish a repeatable update policy so that security patches can be adopted without silently switching all users to unreviewed releases.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (12)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Using --no-check-certificates disables TLS certificate validation for downloads, which permits man-in-the-middle attacks and undermines source authenticity. In this skill's context, the tool fetches attacker-influenced remote media, so disabled certificate checks increase the chance of tampered content or redirection during download.

Content

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

python
cmd = [
        "yt-dlp", url,
        "-o", output_path,
        "--no-check-certificates",
        "--no-update"
    ]
    print("[1/2] 正在下载视频...")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents shell execution, environment-variable modification, and file-writing behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates a real security governance gap because an agent or reviewer cannot clearly constrain what the skill is allowed to execute, increasing the chance of overbroad shell/file access during invocation.

Content

No source excerpt is available for this finding.

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

pip install yt-dlp openai-whisper winget install ffmpeg # Windows

brew install ffmpeg # macOS

sudo apt install ffmpeg # Linux

text

## First-time Setup

Session Persistence

Medium
Category
Rogue Agent
Confidence
81% confidence
Finding

The skill recommends creating a global yt-dlp configuration in user profile directories, which persists beyond the current session and can affect unrelated future uses of yt-dlp. Persistent global changes are risky because they broaden the skill's side effects, can surprise users, and may cause subsequent downloads by other workflows to save files to unintended locations or follow inherited options.

Content

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

yt-dlp global config (optional)

bash
# Windows: Create %APPDATA%\yt-dlp\config (one line):
-o X:\video_downloads\%(title)s.%(ext)s

# macOS/Linux: Create ~/.config/yt-dlp/config (one line):

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

python
"--no-update"
    ]
    print("[1/2] 正在下载视频...")
    result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace')
    if result.returncode != 0 and "already downloaded" not in result.stderr:
        print(f"下载失败: {result.stderr}")
        sys.exit(1)

Tainted flow: 'cmd' from os.environ.get (line 27, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

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

python
"--no-update"
    ]
    print("[1/2] 正在下载视频...")
    result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace')
    if result.returncode != 0 and "already downloaded" not in result.stderr:
        print(f"下载失败: {result.stderr}")
        sys.exit(1)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The embedded Whisper call hard-codes language='zh', which imposes a specific language/locale behavior on all users. The file does not offer an opt-in, fallback, or documented reason that this tool must be Chinese-only, so it matches the policy's language/locale violation criterion.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

The script builds Python source code as a string and executes it with python -c, while embedding untrusted values such as prompt and video_path directly into that code. Because initial_prompt='''{init_prompt}''' can be broken by attacker-supplied triple quotes or crafted content, this creates a code-injection path leading to arbitrary local code execution.

Content

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

python
print('---FULLTEXT---')
print(result['text'])
"""
    result = subprocess.run(
        ["python", "-c", python_code],
        capture_output=True, text=True, encoding='utf-8', errors='replace'
    )

Tainted flow: 'python_code' from os.environ.get (line 61, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
98% confidence
Finding

This is a real code-execution issue, although the dangerous taint source is broader than the finding states: untrusted prompt/path content is interpolated into python_code and then executed. In a skill that accepts external video links and optional prompt text, this makes exploitation more plausible because user input directly influences the generated Python source.

Content

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

python
print('---FULLTEXT---')
print(result['text'])
"""
    result = subprocess.run(
        ["python", "-c", python_code],
        capture_output=True, text=True, encoding='utf-8', errors='replace'
    )

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The description in the front matter is written in Chinese while much of the rest of the document is in English, and the notes also state 'Chinese text optimized with punctuation.' This suggests a language/locale bias without an explicit opt-in or a clearly documented region-specific constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill saves downloaded video content locally, but the description does not prominently warn users of that side effect before invocation. This is a real but low-severity safety issue because users may unintentionally trigger storage, retention, or policy issues when handling copyrighted, sensitive, or large media files.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring says the optional model argument supports "turbo/large-v2", but the code actually defaults to and accepts only 'turbo' or 'large-v3' via the argument check in main. This is an active documentation-to-code contradiction rather than a mere omission.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.