T01 · Skill Instruction Hijacking
- Location
video_pipeline/scripts/enrich_subtitles.py:1377- Finding
Undisclosed Channel-Specific Replacement of Translated Speech
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is mostly a real video dubbing pipeline, but it can silently change the opening translated speech for a configured channel and has broad network behavior that should be reviewed before installation.
Review channel_rules.json before use and disable the intro override unless you explicitly want inserted narration. Install in an isolated environment, pin dependencies if possible, avoid using browser-cookie access unless necessary, and assume subtitle/TTS text may be sent to external translation or TTS providers.
video_pipeline/scripts/enrich_subtitles.py:1377Undisclosed Channel-Specific Replacement of Translated Speech
video_pipeline/scripts/download.py:274Unvalidated Thumbnail URL Enables Server-Side Request Forgery
video_pipeline/scripts/services/volcengine_tts_provider.py:167Unvalidated VolcEngine Audio URL Enables Server-Side Request Forgery
video_pipeline/requirements.txt:1Unbounded Dependency Versions Create Supply-Chain and Build Reproducibility Risk
The documented behavior and declared purpose do not fully align with the operational requirements described in the skill, especially the use of external translation services and unstated network-dependent processing. Misleading or incomplete capability disclosure is dangerous because reviewers and users may approve or invoke the skill without understanding what data leaves the system or what execution privileges are actually required.
Referenced artifact was not completely inspected
pip install -r video_pipeline/requirements.txt
Referenced artifact was not completely inspected
pip install -r video_pipeline/requirements.txt
Launching PowerShell with ExecutionPolicy Bypass weakens an important policy control and normalizes execution of generated scripts outside local policy restrictions. In this code the script is locally generated, so this is not by itself arbitrary code execution, but it does reduce defense-in-depth and increases the blast radius if an attacker can tamper with generated script files or influence the working environment.
The skill declares no explicit tool scope or permissions even though the documentation clearly indicates it needs environment access, filesystem read/write, network access, and shell execution. In an agent ecosystem, this omission can cause the skill to run with broader-than-expected authority or without informed user consent, increasing the risk of misuse or unsafe execution.
The skill description does not clearly warn that user-provided media or derived text may be transmitted to third-party services for translation and possibly TTS/download-related processing. This is a privacy and compliance risk because users may supply copyrighted, confidential, or sensitive audio/video content without understanding that it could be sent off-device to external providers.
The manifest advertises downloading, translating, dubbing, and retiming videos, but it does not warn users that the skill will access third-party services and alter media artifacts. Absent clear disclosure, users may unknowingly authorize network retrieval, processing of copyrighted or sensitive content, and generation of modified outputs they did not expect.
The default prompt is broad enough that many generic requests about videos, translation, subtitles, or dubbing could match it, making accidental or overbroad invocation more likely. In combination with a skill capable of downloading and modifying content from external platforms, vague trigger scope can cause the agent to select this tool when the user did not clearly intend those actions.
allow_implicit_invocation: true permits the skill to be invoked without an explicit user request, increasing the chance the agent will trigger a workflow that downloads and transforms external media unexpectedly. Because this skill performs network access and content modification, implicit invocation raises the risk of surprise execution, unintended external requests, and user-consent bypass.
This JSON config sets the default voice_type to a Chinese-specific voice, and additional channel entries also hard-code Chinese voice variants. Because SQP-3 applies to all file types and covers language/locale policy violations, forcing a specific language/locale in configuration without any visible opt-in or justification is a policy concern.
The per-channel rule assigns a Chinese voice variant directly in configuration, and similar assignments recur in later entries. This indicates the skill behavior is pinned to a specific language/locale rather than offering a choice, which matches the SQP-3 policy example for locale constraints without user opt-in.
The default configuration sets voice_type to zh_male_m191_uranus_bigtts, which is a language/locale-specific choice embedded in code. The file does not present this as an explicit user option or document a justified region-specific constraint, so it constitutes a natural-language locale policy concern.
The code normalizes voice_type and falls back again to zh_male_m191_uranus_bigtts, reinforcing a forced language/locale default. Because no user choice or documented justification is present in this file, this appears to violate the language/locale policy requirement.
The script writes updated subtitle metadata back to the input structured JSON via write_text, and this can modify user data in place as part of normal execution. Although there are informational prints for some later steps, there is no user-facing disclosure at the write site or argument parsing that the input file will be changed.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"1",
"-",
]
result = subprocess.run(command, capture_output=True)
if result.returncode != 0:
stderr = result.stderr.decode("utf-8", errors="ignore").strip()
raise RuntimeError(stderr or f"ffmpeg failed to decode audio: {path}")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"1",
"-",
]
result = subprocess.run(command, capture_output=True)
if result.returncode != 0:
stderr = result.stderr.decode("utf-8", errors="ignore").strip()
raise RuntimeError(stderr or f"ffmpeg failed to decode audio: {path}")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"1",
"-",
]
result = subprocess.run(command, capture_output=True)
if result.returncode != 0:
stderr = result.stderr.decode("utf-8", errors="ignore").strip()
raise RuntimeError(stderr or f"ffmpeg failed to decode audio: {path}")
The ffmpeg command includes -y, which forces overwrite of the destination file without prompting. In an automation pipeline this can silently replace prior outputs, and if an attacker can influence filenames or symlink targets in the output directory, it can contribute to destructive file clobbering.
The script sends subtitle text to an external translator service via translator.translate_sentences(...) without any disclosure or consent mechanism in this file. Because subtitle files may contain proprietary, sensitive, or personal content, silently forwarding them to a third-party service creates a real confidentiality and compliance risk, especially in a batch-processing localization pipeline where users may assume processing is local.
The argument parser description says the script will 'Translate English subtitles to Chinese and build sentence-level structured JSON,' which implies a straightforward translation pipeline. However, the code later calls apply_intro_override() to replace or merge the opening translation with a fixed Chinese intro containing the current production date (L1369-L1400), meaning output is not purely derived from the source subtitles.
The CLI description explicitly states the script will translate English subtitles to Chinese, and the implementation consistently emits Chinese text fields and Chinese intro text. This imposes a specific language/locale on users without offering a choice or documenting a justified region-specific constraint.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
]
print(f"[INFO] Extracting audio from: {video_path.relative_to(PROJECT_ROOT)}")
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(result.stderr.strip() or "ffmpeg failed without stderr output")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
]
print(f"[INFO] Extracting audio from: {video_path.relative_to(PROJECT_ROOT)}")
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(result.stderr.strip() or "ffmpeg failed without stderr output")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
]
print(f"[INFO] Extracting audio from: {video_path.relative_to(PROJECT_ROOT)}")
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(result.stderr.strip() or "ffmpeg failed without stderr output")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
]
print(f"[INFO] Extracting audio from: {video_path.relative_to(PROJECT_ROOT)}")
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(result.stderr.strip() or "ffmpeg failed without stderr output")