Back to skill

Security audit

VoxCPM中文配音

Security checks for vulnerabilities and agentic risk

Overview

This dubbing skill mostly matches its purpose, but it also includes under-disclosed Bilibili publishing code and sends media-derived data to external APIs despite claiming local/data-safe operation.

Review before installing. Use it only if you are comfortable sending transcripts and selected video frames to configured third-party AI endpoints. Remove or ignore scripts/upload_bilibili.py unless you explicitly want Bilibili publishing, and do not place Bilibili session credentials at its hardcoded path unless you intend this skill package to have upload authority.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (15)

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

Medium
Category
Data Flow
Content
frame_path = str(temp_dir / "subtitle_check.jpg")
    ffmpeg = config['ffmpeg_path']
    cmd = [ffmpeg, "-y", "-ss", "30", "-i", video_path, "-vframes", "1", "-q:v", "2", frame_path]
    result = subprocess.run(cmd, capture_output=True)
    
    if not os.path.exists(frame_path):
        print("  [!] 无法提取视频帧,默认不覆盖")
Confidence
86% confidence
Finding
The executable path comes from config/environment via FFMPEG_PATH and is passed directly to subprocess.run. In an agent or multi-tenant environment, a malicious actor who can influence environment variables or config can cause execution of an arbitrary binary instead of ffmpeg.

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

Medium
Category
Data Flow
Content
def run_ffmpeg(cmd):
    result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace')
    return result.returncode == 0
Confidence
84% confidence
Finding
This helper executes arbitrary command arrays supplied by callers, and upstream code builds those arrays with an environment-controlled ffmpeg path. That makes the helper part of an exploitable path to arbitrary code execution if configuration or environment can be influenced.

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

Medium
Category
Data Flow
Content
"-vf", vf, "-map", "0:v", "-map", "1:a",
           "-c:v", codec, "-preset", "default", "-c:a", "aac", output_path]
    
    result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace')
    if result.returncode == 0:
        print(f"[OK] {output_path}")
        return True
Confidence
87% confidence
Finding
The merge step executes ffmpeg using a path sourced from config/environment, enabling arbitrary binary execution if that value is tampered with. Because this skill is likely to run unattended on user media, such configuration abuse could lead to full compromise of the host running the skill.

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

Medium
Category
Data Flow
Content
"-vf", f"subtitles='{srt_escaped}':force_style='{style_str}'",
                  "-map", "0:v", "-map", "1:a",
                  "-c:v", codec, "-preset", "default", "-c:a", "aac", output_path]
    result2 = subprocess.run(cmd_simple, capture_output=True, text=True, encoding='utf-8', errors='replace')
    return result2.returncode == 0
Confidence
87% confidence
Finding
The fallback command repeats the same environment/config-controlled executable risk as the primary merge path. An attacker only needs one reachable subprocess path to replace ffmpeg with a malicious program.

Tainted flow: 'vision_url' from os.environ.get (line 122, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
vision_model = config.get('vision', {}).get('model', 'Qwen/Qwen2.5-VL-72B-Instruct')
    
    try:
        resp = requests.post(
            vision_url,
            headers={"Authorization": f"Bearer {translate_key}", "Content-Type": "application/json"},
            json={
Confidence
97% confidence
Finding
A video frame is base64-encoded and sent to a vision API endpoint that is itself configurable from environment or config, while the Authorization header reuses the translation API key. This creates both data exfiltration and credential exfiltration risk, because an attacker-controlled endpoint can receive sensitive video content and the bearer token.

Tainted flow: 'api_url' from os.environ.get (line 214, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
}
            
            try:
                resp = requests.post(api_url, headers=headers, json=data, timeout=60)
                result = resp.json()
                
                if 'choices' in result:
Confidence
96% confidence
Finding
Transcript text is sent to a translation API URL that can be overridden from the environment, along with a bearer API key. If that endpoint is malicious or misconfigured, both potentially sensitive transcript content and credentials are disclosed externally.

Tainted flow: 'api_url' from os.environ.get (line 214, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
for text in batch:
                for _ in range(3):
                    try:
                        resp = requests.post(
                            api_url,
                            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
                            json={
Confidence
96% confidence
Finding
The per-sentence fallback repeats the same issue as the batch translation path, exposing transcript content and the API key to an arbitrary configured endpoint. Repetition increases exposure because more requests are made and more content may be transmitted after failures.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The documentation claims local execution and data safety, yet other sections state that translation and subtitle-detection content is sent automatically to third-party APIs. This is a misleading security assurance that can cause users to expose sensitive audio, transcript, or frame-derived data under false assumptions about locality and privacy. Misrepresentation of data flow is a security-relevant documentation flaw.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The script performs authenticated publication to a third-party Bilibili account, which materially extends the skill from dubbing/localization into account action automation. In the context of a dubbing skill, undisclosed upload capability is dangerous because it can publish user content or derived content externally, creating privacy, compliance, and account-abuse risk.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The file loads persistent Bilibili credentials from a local JSON file and constructs an authenticated client capable of uploading content. Embedding authenticated third-party publishing capability in a skill whose stated purpose is Chinese dubbing/localization increases the chance of unauthorized posting, misuse of account tokens, and hidden side effects beyond user expectations.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill states that translation and vision APIs are called automatically, but it does not clearly warn users that transcript text and video-derived content may be sent to third-party services. Because the input is user media, this can expose sensitive or copyrighted material without sufficiently informed consent. Automatic external transmission in a media-processing skill raises real privacy and compliance concerns.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The configuration includes third-party API endpoints and an API key field but provides no warning that video, audio, subtitle, or image-derived content may be transmitted to an external service. In a dubbing skill, this can expose sensitive media content and credentials if users assume processing is local or mishandle the API key.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill uploads video frames and transcript-derived content to third-party AI services without any explicit warning, consent, or data-handling disclosure. In the context of user videos, this can expose private imagery, speech content, and metadata to external providers unexpectedly.

External Transmission

Medium
Category
Data Exfiltration
Content
"voxcpm_dir": "./VoxCPM",
  "ffmpeg_path": "ffmpeg",
  "translate": {
    "api_url": "https://api.siliconflow.cn/v1/chat/completions",
    "api_key": "YOUR_API_KEY_HERE",
    "model": "tencent/Hunyuan-MT-7B"
  },
Confidence
90% confidence
Finding
This endpoint indicates that content processed by the skill may be sent to an external API for translation. Because the skill handles user media and derived transcripts, external transmission can create privacy, confidentiality, and compliance risks if users are not clearly informed and if sensitive content is uploaded by default.

External Transmission

Medium
Category
Data Exfiltration
Content
"model": "tencent/Hunyuan-MT-7B"
  },
  "vision": {
    "api_url": "https://api.siliconflow.cn/v1/chat/completions",
    "model": "Qwen/Qwen2.5-VL-72B-Instruct"
  },
  "whisper": {
Confidence
90% confidence
Finding
The vision API endpoint implies frames or image-derived data may be sent to a third-party model, which is especially sensitive in a video-dubbing workflow because visual content can contain personal, confidential, or copyrighted material. Without explicit warnings and controls, users may unknowingly exfiltrate media content to an external provider.

Static analysis

No suspicious patterns detected.