Back to skill

Security audit

Huo15 Influencer Video Skill

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent video-generation skill, but it needs review because it can send user images and scripts to external services and runs FFmpeg with loosely validated, overwrite-capable inputs.

Review before installing. Use it only in an isolated environment with non-sensitive product images and scripts, dedicated provider keys, and a controlled output directory. Confirm costs before rendering, avoid broad automatic activation, and do not process untrusted script JSON until path, overwrite, and numeric-parameter validation is added.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:68
Finding

Unpinned Third-Party Python Dependencies

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:68-69
Vulnerability Type: Supply-chain risk from unpinned dependencies
Risk Level: Medium

Vulnerable Code

bash
brew install ffmpeg
pip install edge-tts requests

Technical Analysis

The installation instructions retrieve the latest available versions of edge-tts and requests without version constraints, integrity hashes, or a dependency lock file. Consequently, two installations performed at different times can resolve to different package versions and transitive dependency trees.

Package installation and subsequent imports execute code supplied by those packages under the privileges of the user running the Skill. If a package account, release pipeline, package artifact, or transitive dependency is compromised, users following these instructions could install attacker-controlled code without any corresponding change to the reviewed Skill repository.

No evidence was found that the Skill intentionally requests a malicious or misspelled package. The issue is the absence of reproducible and integrity-verified dependency resolution.

Attack Path

  1. An attacker compromises an upstream package, maintainer account, release process, or transitive dependency.
  2. The attacker publishes a malicious version to the package index.
  3. A user follows the documented pip install edge-tts requests command.
  4. Pip resolves the unpinned requirement to the malicious release.
  5. Attacker-controlled package code executes during installation or when the Skill imports and invokes the package.

Impact Assessment

Successful exploitation can execute arbitrary code with the privileges of the user installing or running the Skill. Depending on those privileges, this could expose local files, environment variables such as API credentials, generated media, and network access available to the process. The Skill itself does not request elevated operating-system p ...[truncated 80 chars]

Remediation
View remediation

Remediation Suggestions

  1. Provide a reviewed requirements file with exact versions for direct and transitive dependencies.
  2. Generate and verify package hashes, then require hash checking during installation:
    bash
    pip install --require-hashes -r requirements.txt
    
  3. Use a dependency-locking tool such as pip-tools to produce reproducible dependency resolution.
  4. Pin or otherwise reproducibly install FFmpeg where the deployment environment permits it.
  5. Add automated dependency vulnerability scanning and controlled update review.
  6. Install dependencies in an isolated virtual environment under a non-privileged account.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/bgm.py:88
Finding

User-Controlled FFmpeg Filter Graph Injection Through BGM Volume

Content
View full analysis

Vulnerability Details

File Locations: scripts/pipeline.py:247-252; scripts/bgm.py:88-103
Vulnerability Type: Injection into the FFmpeg filter expression language
Risk Level: Medium

Vulnerable Code

The unvalidated script value enters mix_audio:

python
mixed = mix_audio(
    voice["path"],
    bgm_key=script.get("bgm", tpl["bgm"]),
    bgm_volume=script.get("bgm_volume", tpl["bgm_volume"]),
    output=f"{work_dir}/mixed.mp3",
)

It is then interpolated directly into an FFmpeg filter graph:

python
else:
    cmd = [
        "ffmpeg", "-y",
        "-i", voice_path,
        "-stream_loop", "-1", "-i", bgm_path,
        "-filter_complex",
        (
            f"[0:a]volume={voice_volume}[v];"
            f"[1:a]volume={bgm_volume},aloop=loop=-1:size=2e9[b];"
            f"[v][b]amix=inputs=2:duration=first:dropout_transition=0,"
            f"afade=t=out:st={max(0, dur-fade_out):.2f}:d={fade_out}"
        ),
        "-t", f"{dur:.2f}",
        "-c:a", "libmp3lame", "-b:a", "192k",
        output,
    ]

Technical Analysis

bgm_volume is documented as a numeric value from zero to one, but render does not enforce its type, range, or finiteness. JSON therefore permits an attacker to supply a string containing FFmpeg filter separators and additional filter syntax.

The command is safely passed to subprocess.run as an argument array, so this is not operating-system shell injection. Nevertheless, FFmpeg independently parses the -filter_complex argument as a filter-graph language. Directly interpolating untrusted text into that language allows filter-language injection even when shell=False.

Exploitation requires a usable BGM file because the vulnerable branch executes only when find_bgm returns a path. Depending on the filters and protocols supported by the installed FFmpeg build, injected syntax could alter processing, consume excessive resou ...[truncated 1352 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate bgm_volume before passing it to mix_audio:
    python
    import math
    
    raw_volume = script.get("bgm_volume", tpl["bgm_volume"])
    if isinstance(raw_volume, bool) or not isinstance(raw_volume, (int, float)):
        raise TypeError("bgm_volume must be a number")
    bgm_volume = float(raw_volume)
    if not math.isfinite(bgm_volume) or not 0.0 <= bgm_volume <= 1.0:
        raise ValueError("bgm_volume must be between 0.0 and 1.0")
    
  2. Format the validated number explicitly before constructing the filter graph:
    python
    safe_bgm_volume = f"{bgm_volume:.3f}"
    
  3. Apply equivalent finite numeric validation and safe ranges to voice_volume and fade_out.
  4. Validate the complete script against a strict schema before starting TTS, network requests, or FFmpeg.
  5. Run FFmpeg with resource limits and under a restricted account or sandbox where untrusted script files may be processed.
  6. Add tests confirming that strings, booleans, non-finite values, negative values, and values above one are rejected.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (23)

Tainted flow: 'headers' from os.environ.get (line 88, credential/environment) → requests.post (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/pipeline.py (reported line 93)May include surrounding context.

python
"Content-Type": "application/json",
    }

    r = requests.post(f"{ARK_BASE}/contents/generations/tasks",
                      headers=headers, json=body, timeout=60)
    res = r.json()
    if "id" not in res:

Tainted flow: 'headers' from os.environ.get (line 88, credential/environment) → requests.get (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/pipeline.py (reported line 103)May include surrounding context.

python
for _ in range(120):  # 最多 20 分钟
        time.sleep(10)
        d = requests.get(f"{ARK_BASE}/contents/generations/tasks/{task_id}",
                         headers=headers, timeout=30).json()
        st = d.get("status")
        print(f"  [{time.strftime('%H:%M:%S')}] {st}")

Tainted flow: 'body' from os.environ (line 82, credential/environment) → requests.post (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/tts.py (reported line 97)May include surrounding context.

python
"operation": "query",
        },
    }
    r = requests.post(
        f"{VOLC_HOST}/api/v1/tts",
        headers={"Authorization": f"Bearer;{token}"},
        json=body, timeout=60,

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill explicitly instructs use of environment variables, local file reads/writes, network access to external APIs, and shell execution via ffmpeg/pip/brew, yet it declares no explicit tool scope or permission boundaries. In an agent environment, this can lead to overbroad execution authority, making accidental or unauthorized filesystem access, command execution, or outbound requests more likely if the skill is triggered or adapted incorrectly.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The alias/trigger list includes broad phrases such as '生成视频', '产品视频', and '拍视频', which are common everyday requests and can cause unintended activation. Mis-triggering matters more here because the skill can access local files, external APIs, and potentially incur charges, so a false activation may lead to privacy exposure or unwanted spend.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

L309-L312 明确将默认字体设为中文字体 PingFang SC,并整体示例与流程均围绕中文配音与中文字幕展开,但文档未说明这是可配置选项,也未给用户语言/地区选择。对于通用视频生成技能,这种默认固定语言/locale 的自然语言约束可能构成组织语言政策问题。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language content in the script is entirely fixed in Chinese, which indicates the skill is designed to produce a specific language output without offering any user language choice. Under the policy, locale or language constraints should be opt-in or clearly justified as region-specific, which is not documented here.

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

python
bgm_path = find_bgm(bgm_key)

    # 取人声时长
    dur = float(subprocess.check_output([
        "ffprobe", "-v", "error",
        "-show_entries", "format=duration",
        "-of", "default=noprint_wrappers=1:nokey=1",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code invokes ffmpeg with -y, which unconditionally overwrites the destination file without confirmation. Because the output path can be caller-controlled and defaults are derived from input names, this can cause silent data loss or clobber existing files, especially in an automated agent workflow where users may not see prompts or warnings.

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

python
"-c:a", "libmp3lame", "-b:a", "192k",
            output,
        ]
    subprocess.run(cmd, check=True, capture_output=True)
    return output

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

python
"-c:a", "libmp3lame", "-b:a", "192k",
            output,
        ]
    subprocess.run(cmd, check=True, capture_output=True)
    return output

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This video muxing path also uses ffmpeg -y, allowing silent overwrite of any existing output file path supplied to the function. In the context of an automation skill that generates media artifacts, this increases the chance of unintended file replacement and makes destructive behavior easier if upstream inputs are influenced by a user or another component.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring and all CLI/help text are written entirely in Chinese, and the implementation assumes Chinese-specific behavior such as Chinese punctuation handling and Chinese subtitle/font defaults. There is no user opt-in or documented justification that this skill is intentionally limited to a Chinese locale, which creates a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/pipeline.py (reported line 93)May include surrounding context.

python
"Content-Type": "application/json",
    }

    r = requests.post(f"{ARK_BASE}/contents/generations/tasks",
                      headers=headers, json=body, timeout=60)
    res = r.json()
    if "id" not in res:

Tainted flow: 'task_id' from requests.post (line 98, network input) → requests.get (network output)

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

python
for _ in range(120):  # 最多 20 分钟
        time.sleep(10)
        d = requests.get(f"{ARK_BASE}/contents/generations/tasks/{task_id}",
                         headers=headers, timeout=30).json()
        st = d.get("status")
        print(f"  [{time.strftime('%H:%M:%S')}] {st}")

Tainted flow: 'video_url' from requests.get (line 108, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
95% confidence
Finding

The code downloads a video from video_url taken directly from a network response without validating the scheme, host, or destination. If the upstream API, a proxy, or an attacker influencing that response returns an arbitrary URL, this can cause server-side request forgery, unintended internal network access, or downloading untrusted content into a local file for later processing. The risk is amplified because the downloaded file is subsequently handled as media in the pipeline.

Content

Scanner excerpt · scripts/pipeline.py (reported line 109)May include surrounding context.

python
print(f"  [{time.strftime('%H:%M:%S')}] {st}")
        if st == "succeeded":
            video_url = d["content"]["video_url"]
            with requests.get(video_url, stream=True, timeout=120) as vr:
                with open(output, "wb") as f:
                    for chunk in vr.iter_content(8192):
                        f.write(chunk)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The ffmpeg invocation passes user-influenced paths directly to a powerful external binary. Although subprocess.run is used with an argument list rather than a shell, reducing classic shell-injection risk, ffmpeg's subtitles filter still interprets the provided SRT path and filter arguments itself; malformed or attacker-controlled paths can trigger unintended file access, filter parsing issues, or abuse of ffmpeg processing behavior. The skill context increases risk because script-controlled output locations and subtitle generation are part of the normal workflow.

Content

Scanner excerpt · scripts/pipeline.py (reported line 161)May include surrounding context.

python
"-c:a", "copy",
        video_out,
    ]
    subprocess.run(cmd, check=True, capture_output=True)
    return video_out

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file’s natural-language content, labels, categories, and configured TTS voices are all fixed to Chinese/zh-CN, with no indication that users may opt into another language or locale. Under the policy, locale-specific behavior should either offer user choice or be clearly documented as a justified region-specific constraint.

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

python
def _probe_duration(audio_path: str) -> float:
    """用 ffprobe 测时长(秒)"""
    out = subprocess.check_output([
        "ffprobe", "-v", "error",
        "-show_entries", "format=duration",
        "-of", "default=noprint_wrappers=1:nokey=1",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-provided text is sent to an external TTS service (edge-tts and potentially Volcano TTS), but the module contains no consent, minimization, or disclosure controls. In a skill that may process product scripts or user-supplied content, this creates a privacy and data-governance risk if sensitive or proprietary text is synthesized remotely without clear notice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module defaults to Chinese voices such as zh-CN-XiaoqiuNeural, and the exposed voice list only contains Chinese locale voices. This imposes a specific language/locale behavior without offering user choice or documenting that the skill is intentionally China/Chinese-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The module automatically reads environment-based credentials and transmits content to a remote vendor API without any in-code disclosure, confirmation, or policy gating. While standard for service integration, this is still a real privacy/compliance issue because remote processing is silently enabled when credentials are present.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

This code transmits text content and authentication material to an external TTS endpoint, which is expected for cloud TTS but still expands the trust boundary. In the context of a video-generation skill that may handle marketing scripts, prompts, or potentially user-supplied content, external transmission can expose sensitive business or personal data if not disclosed and controlled.

Content

Scanner excerpt · scripts/tts.py (reported line 97)May include surrounding context.

python
"operation": "query",
        },
    }
    r = requests.post(
        f"{VOLC_HOST}/api/v1/tts",
        headers={"Authorization": f"Bearer;{token}"},
        json=body, timeout=60,

Static analysis

No suspicious patterns detected.