Back to skill

Security audit

article-to-video

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real article-to-video tool, but it has under-contained local file deletion and cleanup behavior that could remove files outside the intended outputs.

Install only if you are comfortable granting this skill local media-generation authority. Use it in a contained workspace, avoid untrusted filenames and output directories, and treat the BGM manager as administrative until path confinement, delete confirmation, and unique temporary directories are fixed.

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

Error
Location
scripts/bgm_manager.py:203
Finding

Path Traversal in BGM Upload and Removal Operations

Content
View full analysis
Tuple[bool, str]: """Remove a BGM file from a style directory. Args: style_name: BGM style directory name filename: Filename to remove Returns: (success, message) """ if style_name not in BGM_CONFIG["styles"]: return False, f"Unknown style: '{style_name}'" style_dir = get_style_dir(style_name) file_path = os.path.join(style_dir, filename) if not os.path.exists(file_path): return False, f"File not found: {file_path}" # Safety check: only allow audio file extensions if not filename.lower().endswith(('.mp3', '.m4a', '.wav')): return False, f"Refusing to remove non-audio file: {filename}" os.remove(file_path) return True, f"Removed: {file_path}" ``` ### Technical Analysis The removal function directly joins an attacker-controlled filename to the configured BGM style directory. It does not reject absolute paths, parent-directory components, or path separators, and it does not verify that the resolved path remains inside the intended BGM directory. The extension check does not prevent traversal. For example, `../../target.mp3 ...[truncated 2237 chars]
Remediation
View remediation
Path: if not filename or filename != Path(filename).name: raise ValueError("Only a plain filename is allowed") if "/" in filename or "\\" in filename or ".." in Path(filename).parts: raise ValueError("Path separators and parent traversal are forbidden") if Path(filename).suffix.lower() not in {".mp3", ".m4a", ".wav"}: raise ValueError("Unsupported audio extension") base = Path(style_dir).resolve(strict=True) candidate = (base / filename).resolve(strict=False) if not candidate.is_relative_to(base): raise ValueError("Destination escapes the BGM directory") return candidate ``` Apply the same confinement helper before `os.remove()`, `shutil.copy2()`, and force-overwrite handling. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/assemble_video.py:740
Finding

Predictable Shared Temporary Directory Is Recursively Deleted

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (60)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says the skill performs article/document-to-video generation with narration, visuals, and TTS. The supplied code does none of that. Its actual purpose is managing a background-music asset library under assets/bgm/, including file validation, upload, listing, deletion, and configuration display. This is a materially different primary purpose and includes filesystem management capabilities not reflected in the description. Therefore, the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code is only the document parsing/stage-building component of a larger pipeline. It reads supported document types, extracts text structure, builds scenes, estimates durations, detects content type, and creates textual prompts for image generation. However, it does not generate narrated videos, synthesize speech, or create visuals. Because the declared purpose describes an end-to-end article/document-to-video capability, while this code chunk implements only an upstream parser/preprocessor, the description materially overstates what the supplied code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear mismatch between the declared purpose and the actual code behavior. The description promises article/document-to-video generation with AI visuals and TTS narration. However, this code chunk contains only tests for BGM management functionality: path resolution, audio validation, file listing, upload/delete behavior, and configuration consistency checks. No document parsing, video generation, image generation, narration synthesis, or text-to-video pipeline behavior appears in this chunk. The code’s primary purpose is audio asset/library management, which is materially different from the declared skill purpose.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · scripts/bgm_manager.py (reported line 181)May include surrounding context.

python
source_path: Path to the source audio file
        style_name: Target BGM style (e.g. "corporate", "cinematic")
        rename: Optional new filename (if None, use original filename)
        force: If True, overwrite existing file with the same name

    Returns: (success, message)
    """

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · tests/test_bgm_manager.py (reported line 245)May include surrounding context.

python
source_path: Path to the source audio file
        style_name: Target BGM style (e.g. "corporate", "cinematic")
        rename: Optional new filename (if None, use original filename)
        force: If True, overwrite existing file with the same name

    Returns: (success, message)
    """

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · scripts/bgm_manager.py (reported line 358)May include surrounding context.

python
choices=list(BGM_CONFIG["styles"].keys()),
                         help="Target BGM style")
    p_upload.add_argument("--name", "-n", default=None, help="Rename file (without extension)")
    p_upload.add_argument("--force", action="store_true", help="Overwrite existing file")

    # remove
    p_remove = subparsers.add_parser("remove", help="Remove BGM file")

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/parse_doc.py (reported line 343)May include surrounding context.

python
if AI_IMAGE_CONFIG.get("no_text", True):
        prompt += "No text in image. "
    prompt += "High quality, detailed, suitable for educational video."
    return prompt


# ============================================================

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill describes capabilities that imply file reads/writes, shell execution, and network access, but it does not declare any explicit tool scope or allowed-tools boundary. This weakens least-privilege controls and can let a runtime grant broader access than users expect, especially since the workflow includes document parsing, ffmpeg invocation, TTS services, and asset management.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The invocation text is broad enough that the skill may trigger on common article, document, or text-to-video requests without clear exclusion criteria. Overbroad matching can cause the agent to invoke a powerful skill with filesystem, shell, and network behaviors in contexts where the user did not intend such processing.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The 'When to Use' triggers are generic and lack boundaries, which increases the chance of accidental or policy-bypassing invocation. In a skill that can read uploaded documents, call external services, write outputs, and run ffmpeg, unnecessary invocation expands data exposure and execution risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The available voice list is presented only in Chinese voices, and later defaults specify a Chinese subtitle font, indicating a language/locale assumption rather than an explicit user choice. The documentation does not offer a language selection flow or state that these Chinese-specific defaults are optional based on user preference.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The text specifies 'C:/Windows/Fonts/msyh.ttc (Microsoft YaHei)' as the default subtitle font, which implies a specific language/locale choice. There is no accompanying opt-in, user choice, or justification that this skill is intended only for Chinese-language or region-specific output.

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

python
"""
    cmd = [PATHS_CONFIG["ffmpeg"], "-y", "-hide_banner", "-loglevel", "warning"] + args
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
        if check and result.returncode != 0:
            return False, result.stderr
        return result.returncode == 0, result.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/assemble_video.py (reported line 297)May include surrounding context.

python
# Fallback: parse ffmpeg -i stderr output
    try:
        result = subprocess.run(
            [PATHS_CONFIG["ffmpeg"], "-i", video_path],
            capture_output=True, text=True, timeout=10
        )

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

python
# Fallback: parse ffmpeg -i stderr output
    try:
        result = subprocess.run(
            [PATHS_CONFIG["ffmpeg"], "-i", video_path],
            capture_output=True, text=True, timeout=10
        )

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

python
# Try ffprobe first
    try:
        result = subprocess.run(
            [PATHS_CONFIG["ffprobe"], "-v", "error",
             "-select_streams", "a",
             "-show_entries", "stream=codec_name",

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill manifest describes converting articles/documents into narrated videos, but this file is a separate command-line manager for maintaining a background-music asset library, including upload, removal, validation, and inventory operations. Managing a reusable media library is not an obvious implementation detail of a document-to-video conversion skill because it introduces independent asset administration capabilities rather than directly performing article-to-video generation.

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

python
# Tier 1: Try ffprobe to verify audio stream
    try:
        result = subprocess.run(
            [PATHS_CONFIG["ffprobe"], "-v", "error",
             "-show_entries", "format=duration,bit_rate",
             "-show_entries", "stream=codec_name,channels,sample_rate",

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

python
# Tier 2: Use bundled ffmpeg -i to check if the file has valid audio
    try:
        result = subprocess.run(
            [PATHS_CONFIG["ffmpeg"], "-i", file_path, "-f", "null", "-",
             "-t", "0.1"],  # Only decode 0.1s to speed up validation
            capture_output=True, text=True, timeout=10

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code allows arbitrary local media library modification through upload and deletion operations, which is more sensitive than ordinary article-to-video conversion behavior. In a skill context, this expands the blast radius from content generation to persistent asset tampering, enabling unauthorized replacement or removal of background music if this tool is exposed to untrusted users or agents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code performs an irreversible delete with os.remove(file_path) as part of the remove command, but there is no confirmation prompt before the deletion occurs. Although the CLI help says "Remove BGM file," the code itself provides no pre-action disclosure or confirmation for this destructive operation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The default TTS voice is set to a Chinese locale voice (zh-CN-XiaoxiaoNeural), which makes the skill produce Chinese-language narration by default. This is a natural-language locale choice imposed by configuration, and the file does not indicate any user opt-in or explicit locale selection before applying it.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The font selection hard-codes Chinese-capable fonts such as Microsoft YaHei, SimHei, and NotoSansCJK, and the supported platform example later includes a China-specific platform. This indicates a locale-specific design, but the script does not disclose that limitation or offer a language/locale opt-in, which can violate language-choice policy for general-purpose skills.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documented example uses a Chinese voice (zh-CN-XiaoxiaoNeural), the gTTS fallback maps voices containing zh to zh-cn, and the offline fallback explicitly tries to select a Chinese voice. This imposes a language/locale preference in the skill behavior rather than offering a neutral default or explicit user language choice.

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

python
# Tier 1: Try ffprobe
    try:
        result = subprocess.run(
            [PATHS_CONFIG["ffprobe"], "-v", "error",
             "-show_entries", "format=duration",
             "-of", "default=noprint_wrappers=1:nokey=1",

Static analysis

No suspicious patterns detected.