Back to skill

Security audit

video-audio-replace

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it needs review because it encourages unsafe privileged package installation and can send subtitle text to third-party TTS services without a clear privacy warning.

Review before installing. Use an isolated virtual environment with pinned dependencies, do not follow the sudo pip3 --break-system-packages instruction, avoid running this as root, and only use ElevenLabs or Edge TTS with subtitle text you are comfortable sending to those providers. Be cautious on shared machines because the tool uses predictable temporary paths under /tmp.

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
generate_subtitles.py:14
Finding
Unpinned dependencies and unsafe privileged installation guidance<![CDATA[ ## Vulnerability Details **File Location**: `generate_subtitles.py:14-17`; related declarations in `SKILL.md:26` and `_meta.json:11-14` **Vulnerability Type**: Unpinned third-party dependencies and privileged system-wide package installation **Risk Level**: Medium ### Complete Code Snippets `generate_subtitles.py:14-17`: ```python except ImportError: print("Error: faster-whisper not installed.") print("Install with: sudo pip3 install faster-whisper --break-system-packages") sys.exit(1) ``` `SKILL.md:26`: ```bash pip install faster-whisper srt ``` `_meta.json:11-14`: ```json "requirements": { "pip": ["requests", "srt", "faster-whisper", "edge-tts"], "system": ["ffmpeg"] } ``` ### Technical Analysis The project specifies third-party Python packages without locking their versions or verifying package hashes. Consequently, the effective dependency code can change between installations without any corresponding change to the audited Skill. The error message in `generate_subtitles.py` recommends running `pip3` through `sudo` and using `--break-system-packages`. Python packages can execute arbitrary installation and build code. Following this recommendation therefore extends root privileges to all code involved in package resolution, download, build, and installation. The `--break-system-packages` option also bypasses protections intended to prevent unmanaged modifications to the operating system's Python environment. No evidence establishes that the currently named packages are malicious. The vulnerability is the unsafe and excessive installation method and the absence of reproducible dependency constraints. ### Attack Path 1. An attacker compromises a future release, build dependency, maintainer account, or package distribution path associated with one of the unpinned dependencies. 2. A user encounters the missing-dependency message and follows the displayed `sudo pip3 install ... --break-system-packages` instruction. 3. `pip` r ...[truncated 1072 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `sudo` and `--break-system-packages` from all installation guidance. 2. Require installation inside an isolated virtual environment, for example: ```bash python3 -m venv .venv . .venv/bin/activate python -m pip install --require-hashes -r requirements.txt ``` 3. Pin every direct and transitive dependency to a reviewed version in a lock file. 4. Record cryptographic hashes and install with `--require-hashes`. 5. Use only canonical, authenticated package repositories and explicitly configure the expected index. 6. Regularly scan locked dependencies for known vulnerabilities and review updates before changing the lock file. 7. Treat system dependencies such as `ffmpeg` similarly by documenting trusted installation sources and supported versions. 8. Replace the runtime installation prompt with a non-privileged message referring users to the locked environment setup documentation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
replace.py:121
Finding
Predictable shared temporary files permit symlink attacks and cross-process interference<![CDATA[ ## Vulnerability Details **File Location**: `replace.py:121-132` and `replace.py:172-174` **Vulnerability Type**: Unsafe predictable temporary files and directories **Risk Level**: Medium ### Complete Code Snippets `replace.py:121-132`: ```python def concat_audio(files, output_file): """Concatenate multiple audio files""" concat_list = "/tmp/concat_list.txt" with open(concat_list, 'w') as f: for file in files: f.write(f"file '{file}'\n") subprocess.run([ "ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", concat_list, "-c", "copy", output_file ], capture_output=True) os.remove(concat_list) ``` `replace.py:172-174`: ```python # Create temp directory temp_dir = "/tmp/video_audio_replace" os.makedirs(temp_dir, exist_ok=True) ``` ### Technical Analysis The Skill stores intermediate data in globally predictable paths under `/tmp`. The concat manifest always uses `/tmp/concat_list.txt`, while every invocation shares `/tmp/video_audio_replace` and predictable names such as `original.mp3`, `tts_000.mp3`, and `aligned_000.mp3`. Opening `/tmp/concat_list.txt` with mode `w` is not an atomic secure temporary-file operation and follows symbolic links. A local attacker who can prepare that path before execution may redirect the write to another file writable by the victim. If the Skill runs with elevated privileges, the target set expands to files writable by that privileged account. The shared directory also permits collisions between concurrent executions. An attacker or another invocation can replace or modify intermediate files between creation and consumption, causing output corruption or attacker-influenced media processing. The code does not verify path ownership, reject symbolic links, apply private directory permissions, or isolate each invocation. ### Attack Path 1. A local attacker predicts that the victim will run the Skill. 2. Before execution, the attacker creates `/tmp/concat_list ...[truncated 1320 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a unique private directory for every invocation: ```python import tempfile with tempfile.TemporaryDirectory(prefix="video_audio_replace_") as temp_dir: # Keep every intermediate artifact inside temp_dir. ... ``` 2. Create the concat manifest securely inside that directory using `tempfile.NamedTemporaryFile`, rather than using a fixed global path. 3. Ensure temporary directories and files are accessible only to the current user, normally with directory mode `0700` and file mode `0600`. 4. Do not follow attacker-controlled symbolic links. Where persistent output files must be opened directly, use safe open flags such as `O_NOFOLLOW`, `O_CREAT`, and `O_EXCL` where supported. 5. Pass the unique manifest path to `ffmpeg` and keep all generated media under the same private directory. 6. Use a `try`/`finally` block or temporary-directory context manager to guarantee cleanup after errors. 7. Check every `subprocess.run` result with `check=True` and stop processing when `ffmpeg` or `ffprobe` fails. 8. Explicitly document that the media workflow must not be run as root or through `sudo`. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The supplied code chunk implements only the subtitle-generation portion of the declared description. It loads a Whisper model, transcribes the input video, formats segment timestamps, and outputs an .srt file. It does not perform the skill's primary declared behavior of replacing video audio with synthesized speech, nor does it call ElevenLabs or Edge TTS, modify video/audio tracks, align generated speech to the original audio timing in the described way, adjust speed, or insert silence. Because the declared purpose presents a broader dubbing/TTS pipeline while this code only handles subtitle generation, the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Most of the declared audio-replacement behavior is accurately represented: the script takes a video and subtitle file, generates TTS with ElevenLabs or Edge, aligns each segment to subtitle timestamps, adjusts speed using ffmpeg atempo with a user-supplied range, adds silence, concatenates segments, and muxes the new audio into the video. However, the description also claims 'Includes subtitle generation from video using Whisper,' which is a material declared capability not implemented here. The script requires --srt as an input and contains no Whisper import, transcription logic, or subtitle extraction from the video. This is a description-behavior mismatch due to a missing declared feature, though there are no obvious undeclared unrelated or malicious capabilities.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documents capabilities that imply shell execution, file reads/writes, environment-variable access, and network use, but it does not declare any tool scope or permission boundaries. In an agent environment, that omission weakens least-privilege controls and can allow broader-than-expected access when processing user-supplied video, subtitles, and API credentials.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill encourages use of ElevenLabs or Edge TTS without clearly warning that subtitle text derived from the user's video may be transmitted to third-party services. Because subtitles can contain sensitive spoken content, users may unknowingly disclose private, proprietary, or regulated information to external providers.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
from faster_whisper import WhisperModel
except ImportError:
    print("Error: faster-whisper not installed.")
    print("Install with: sudo pip3 install faster-whisper --break-system-packages")
    sys.exit(1)
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The skill description says it includes subtitle generation from video using Whisper, which implies code that transcribes the video audio into subtitles. In this file, the CLI requires an existing --srt input and there is no Whisper import, invocation, or transcription logic anywhere; the implementation only replaces audio based on provided subtitles.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def get_duration(filepath):
    """Get audio/video duration in seconds"""
    result = subprocess.run(
        ["ffprobe", "-v", "error", "-show_entries", "format=duration",
         "-of", "default=noprint_wrappers=1:nokey=1", filepath],
        capture_output=True, text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
Subtitle text is transmitted to a third-party TTS provider, which may contain sensitive or copyrighted content, without any prominent warning, consent flow, or privacy guardrails. In a media-processing skill, users may reasonably expect local transformation unless cloud transmission is made explicit, so the context increases the privacy risk.

External Transmission

Medium
Category
Data Exfiltration
Content
def generate_elevenlabs(text, output_path, voice_id, api_key):
    """Generate audio using ElevenLabs API"""
    url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}"
    headers = {
        "Accept": "audio/mpeg",
        "Content-Type": "application/json",
Confidence
90% confidence
Finding
The hardcoded ElevenLabs endpoint confirms that this tool relies on a third-party service for some processing, which creates a privacy and data-governance risk when handling subtitle text. The danger is contextual rather than malicious: users may unknowingly send content off-device.

External Transmission

Medium
Category
Data Exfiltration
Content
"voice_settings": {"stability": 0.5, "similarity_boost": 0.75}
    }

    response = requests.post(url, json=data, headers=headers)
    if response.status_code == 200:
        with open(output_path, 'wb') as f:
            f.write(response.content)
Confidence
92% confidence
Finding
This code sends subtitle contents to an external API over the network, which is a real data-exposure event. While this is part of the feature, it becomes security-relevant because the transmitted text may include sensitive content and the skill does not appear to enforce explicit consent or minimization.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def extract_original_audio(video_file, output_file):
    """Extract audio from video"""
    subprocess.run([
        "ffmpeg", "-y", "-i", video_file, "-vn", "-acodec", "mp3",
        "-ar", "44100", "-ac", "1", output_file
    ], capture_output=True)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def split_audio(audio_file, start_time, duration, output_file):
    """Split audio file from start_time for duration"""
    subprocess.run([
        "ffmpeg", "-y", "-i", audio_file, "-ss", str(start_time),
        "-t", str(duration), "-vn", "-acodec", "mp3", output_file
    ], capture_output=True)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def adjust_speed(input_file, output_file, speed_ratio):
    """Adjust audio speed using atempo"""
    subprocess.run([
        "ffmpeg", "-y", "-i", input_file, "-filter:a", f"atempo={speed_ratio}",
        "-vn", output_file
    ], capture_output=True)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def add_silence(duration, output_file):
    """Generate silence audio"""
    subprocess.run([
        "ffmpeg", "-y", "-f", "lavfi", "-i", f"anullsrc=r=44100:cl=mono",
        "-t", str(duration), "-q:a", "9", output_file
    ], capture_output=True)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
for file in files:
            f.write(f"file '{file}'\n")

    subprocess.run([
        "ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", concat_list,
        "-c", "copy", output_file
    ], capture_output=True)
Confidence
76% confidence
Finding
The concat list is written using raw file paths into ffmpeg's concat demuxer format with -safe 0, but paths are not escaped or validated. If an attacker can influence file names written into the list, specially crafted names containing quotes or concat directives could alter ffmpeg's interpretation, causing unintended file access or processing behavior.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
silence_file = audio_file + ".silence.mp3"
    add_silence(silence_duration, silence_file)

    subprocess.run([
        "ffmpeg", "-y", "-i", audio_file, "-i", silence_file,
        "-filter_complex", "[0:a][1:a]concat=n=2:v=0:a=1[out]",
        "-map", "[out]", output_file
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def replace_video_audio(video_file, audio_file, output_file):
    """Replace video audio with new audio"""
    subprocess.run([
        "ffmpeg", "-y", "-i", video_file, "-i", audio_file,
        "-c:v", "copy", "-c:a", "aac", "-b:a", "192k",
        "-map", "0:v:0", "-map", "1:a:0",
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
silence_file = f"{temp_dir}/end_silence.mp3"
        add_silence(silence_needed, silence_file)

        subprocess.run([
            "ffmpeg", "-y", "-i", merged_audio, "-i", silence_file,
            "-filter_complex", "[0:a][1:a]concat=n=2:v=0:a=1[out]",
            "-map", "[out]", final_audio
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Context-Inappropriate Capability

Low
Confidence
78% confidence
Finding
The manifest focuses on replacing video audio and generating subtitles, but does not mention reading secrets from environment variables or credential-dependent operation. Accessing ELEVENLABS_API_KEY introduces a credential-handling capability beyond the core local media-processing purpose unless the manifest explicitly scopes external authenticated TTS use.

Static analysis

No suspicious patterns detected.