Back to skill

Security audit

人物说唱视频制作官

Security checks for vulnerabilities and agentic risk

Overview

This video-making skill needs review because its bundled upload tools can publish unrelated local files and delete source material even when transfers fail.

Use an isolated workspace with backups and only media approved for public access. Before use, constrain plan paths to the project, disable directory replacement and automatic source deletion, and restrict hosting-directory permissions. The main wrapper preserves originals; the standalone uploader needs --keep-source, since --no-purge-project alone does not preserve them. Public exposure is disclosed, but these containment and data-loss defects warrant review. External services were not exercised.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/material-uploader/upload_assets.py
Finding

Uploaded asset directories are explicitly made world-writable

Content
View full analysis

Impact

Other local users can remove or replace published images, audio, or clips, including files whose own permissions prohibit writes. Downstream generation can consume substituted material, and public asset availability and integrity can be compromised.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/material-uploader/upload_assets.py
Finding

Default project purge deletes sources that failed copying or verification

Content
View full analysis

Impact

Original files can be irreversibly lost despite unsuccessful transfer or failed public accessibility checks. With copy failures, affected originals may have no valid destination copy. The final failure exit occurs only after cleanup.

Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (88)

Tainted flow: 'req' from os.environ.get (line 276, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/material-uploader/upload_assets.py (reported line 277)May include surrounding context.

python
code = "ERR"
    try:
        req = urllib.request.Request(url, method="HEAD")
        with urllib.request.urlopen(req, timeout=10) as resp:
            code = resp.status
    except urllib.error.HTTPError as exc:
        code = exc.code

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

仓库只提交模板,不提交任何密钥。所有 key / 本地地址都放 .env:

bash
cp env.example .env
# 编辑 .env

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

bash
cp env.example .env
# 编辑 .env

.env 已在 .gitignore 中,不会进 Git。脚本启动时会自动读取。

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
cd mv-sing-opener-skill
pip install -r requirements.txt

# 准备:所有 key / 本地地址放 .env,不要把 .env 提交到仓库
cp env.example .env

# 0) 建档(有图带 --image;无图先空着)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
pip install -r requirements.txt

# 准备:所有 key / 本地地址放 .env,不要把 .env 提交到仓库
cp env.example .env

# 0) 建档(有图带 --image;无图先空着)
python3 scripts/new_project.py --slug <短名> --duration 30

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · requirements.txt (reported line 12)May include surrounding context.

text
# - 上传目标:/var/www/public/mv(本机没有就到服务器/容器跑,--dry-run 可预览)
# - 出片网关:scripts/config.json 的 gateway_base(默认 <redacted-url>
#   可用环境变量 VIDEO_GATEWAY_BASE 覆盖)
# - 出图接口:.env 的 NEWAPI_IMAGE_*

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/README.md (reported line 15)May include surrounding context.

首次使用:

bash
cp env.example .env
# 编辑 .env:NEWAPI_IMAGE_KEY / ASSET_URL_BASE / ASSET_DEST_DIR / VIDEO_GATEWAY_BASE

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

python
PLAN_NAME = "分镜JSON.json"
PROMPTS_NAME = "文生图提示词.json"

# 本地环境变量:.env 不进 Git,密钥/本地地址都放这里
ENV_PATH = SKILL_ROOT / ".env"

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The script implements a relevant video-rendering component, so gateway calls, downloads, ffmpeg processing, and output-file management are supporting details rather than mismatches. However, its executable paths materially exceed or bypass explicit scope restrictions in the description. In particular, it can submit audio-free generation requests, process reference videos and extension chains, and forward raw requests without enforcing the advertised audio, ratio, or duration requirements. The absence of the broader creative workflow in this single supplied component is not itself treated as a mismatch; the finding rests on directly observable contradictory capabilities.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Most operations are legitimate final-assembly support, and the script does not accelerate audio. However, subtitle burning directly violates a declared visual constraint. In resolve_local(), project / p can resolve outside the project when p is absolute or contains '..', so audio lookup is not confined to approved project inputs. Finally, audio duration is only printed; FFmpeg receives -t based on storyboard totals, allowing a result shorter than the supplied audio. The absence of upstream creative stages in this assembly-only chunk is not itself treated as a mismatch.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The document explicitly states that material-uploader with overwrite_dir:true deletes the entire remote directory before writing, potentially removing previously uploaded images when only audio is supplied. Its recommendation to upload the whole project can also expose archived inputs and internal records unless uploads are restricted; the separate allegations of default local-source deletion are not verifiable from the supplied file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

逐镜生成、合并、音轨回贴和裁剪属于声明用途的正常实现细节。但代码不仅包含字幕选项,还明确执行烧录字幕的命令,产生声明明确禁止的画面文字。所给片段未展示脚本内部实现,因此不据此推断其他资源访问或额外能力,也不将未展示的创作流程视为不匹配。

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Asset uploading, generation, merging, and audio assembly are supporting steps consistent with the declared video-production purpose. However, the documented subtitle-burning command introduces readable on-screen text, directly contradicting an explicit visual constraint. The underlying scripts are not supplied, so their internal behavior and compliance with other requirements cannot be verified from this chunk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The project scaffolding, local image copies, and registry updates are legitimate supporting implementation details, and this initialization script need not implement the entire video workflow. However, its explicit alternative aspect-ratio options depart from the declared output format. Its hard-coded fallback visual style also conflicts with the promise of input-specific creative planning. Uploading and generation are only mentioned in generated documents; the supplied code does not perform those operations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The QA role, local report writing, media probing and optional link checks are supporting implementation details, not unrelated capabilities. However, the validator explicitly accepts non-9:16 plans and does not enforce the declared audio-source boundary or mandatory audio availability. These are concrete discrepancies with the skill's stated constraints. The supplied chunk does not itself generate videos or demonstrate that downstream production actually proceeds without audio.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The remote overwrite hazard is corroborated by the warning that overwrite_dir:true first deletes the whole destination directory, which can destroy previously uploaded project assets. The document warns about the hazard but does not require a non-destructive setting or confirmation; local cleanup and standalone source-deletion claims remain unverified.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

Public uploading is disclosed in the workflow, so it is not hidden behavior, but there is no explicit user-facing privacy warning or separate authorization gate for publishing facial images and vocal recordings. Mandatory public links can expose sensitive media to anyone obtaining the URLs; the alleged video-input and external-path behaviors are not independently verifiable here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

Most visible steps support the declared video-production purpose. However, python3 scripts/assemble.py assets/output/MV01-<短名> --subtitle explicitly enables a subtitle-related feature despite the description's prohibition on readable on-screen text. This is a concrete workflow-level mismatch. The underlying scripts are not supplied, so the exact subtitle rendering behavior and enforcement of other constraints cannot be verified. Dependency installation, asset uploads, and project logging are supporting implementation details, not independent mismatches.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

Material uploading and project asset management could support the declared purpose. However, the explicitly documented ability to clear an arbitrary directory is a broader destructive filesystem capability not disclosed in the description. The supplied chunk is documentation rather than the uploader implementation, so it establishes the advertised clearing capability but does not verify its implementation or exact deletion scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

Most commands are supporting implementation details consistent with the declared video-production purpose. However, python3 scripts/assemble.py "$P" --subtitle explicitly requests subtitle-related behavior, which appears to contradict the description’s zero-readable-text requirement. The assembly script is not supplied, so actual subtitle rendering cannot be confirmed; the mismatch assessment rests on the explicit option in the provided workflow. The excerpt does not establish violations of the audio-speed, shot-duration, or creative-process requirements.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
87% confidence
Finding

视频组装本身属于声明用途的配套实现,不构成不匹配。但 --subtitle --burn 明确指向将可读字幕嵌入成片,与声明的无文字画面约束相悖。由于仅提供了 README 命令而未提供 assemble.py 实现,无法验证这些参数是否实际生效,也无法评估其余制作流程。

Content

No source excerpt is available for this finding.

The upload workflow lacks a user-facing warning about public exposure of facial images and audio.

High
Category
Output Handling
Confidence
90% confidence
Finding

This workflow makes uploading facial images and voice recordings to publicly accessible URLs a mandatory step without requiring an explicit public-exposure acknowledgement at that step. An agent following this source can publish personally identifying media when the user intended only private video processing, and successful HEAD checks verify availability rather than authorization or privacy.

Content

No source excerpt is available for this finding.

L007 instructs the agent to delete old-project audio without warning the user about potential data loss.

High
Category
Output Handling
Confidence
97% confidence
Finding

The instruction broadly requires deleting old-project audio without restricting deletion to disposable copies in the current project or requesting confirmation. An agent following it could destroy unrelated user recordings while trying to enforce the current-project audio requirement.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/_common.py (reported line 39)May include surrounding context.

python
PROMPTS_NAME = "文生图提示词.json"

# 本地环境变量:.env 不进 Git,密钥/本地地址都放这里
ENV_PATH = SKILL_ROOT / ".env"


def _load_env_file() -> None:

Unvalidated Output Injection

High
Category
Output Handling
Confidence
95% confidence
Finding

This duplicates the concat-manifest injection issue: filenames derived from shot IDs are written verbatim inside quoted manifest records. Quotes and newlines can alter those records and introduce unintended local media inputs; this is FFmpeg manifest injection, not shell-command execution.

Content

Scanner excerpt · scripts/generate_video.py (reported line 841)May include surrounding context.

python
for f in files:
            handle.write(f"file '{f.resolve()}'\n")
    try:
        result = subprocess.run(
            ["ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", str(list_path),
             "-c", "copy", str(output)],
            capture_output=True, text=True, timeout=timeout,