Back to skill

Security audit

add narration to a video automatically

Security checks for vulnerabilities and agentic risk

Overview

This skill is coherent for creating narrated videos, but its bundled TTS script has a real command/code injection risk and sends narration text to an external TTS service.

Install only if you trust the local inputs passed to the scripts and are comfortable reviewing or fixing the TTS script first. Avoid using sensitive screen-recording content with the remote TTS path unless disclosure is acceptable, run dependencies in a virtual environment, and avoid output paths where silent overwrite would matter.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate-tts.sh:19
Finding
Arbitrary Python Code Injection Through Shell Argument Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-tts.sh`, lines 19–39 **Vulnerability Type**: Python source injection through an unquoted, shell-expanded heredoc **Risk Level**: High ### Vulnerable Code ```bash python3 << PYEOF import asyncio import json import edge_tts with open("$SECTIONS_JSON") as f: segments = json.load(f) voice = "$VOICE" rate = "$RATE" output_dir = "$OUTPUT_DIR" async def generate(): for i, text in enumerate(segments, 1): comm = edge_t_tts.Communicate(text, voice, rate=rate) fname = f"{output_dir}/seg{i:02d}.mp3" await comm.save(fname) print(f"Generated {fname}") asyncio.run(generate()) PYEOF ``` The source file uses `edge_tts.Communicate` rather than `edge_t_tts.Communicate`; the spelling above should be read as the corresponding `edge_tts.Communicate` call shown in the audited file. ### Technical Analysis The heredoc delimiter is unquoted, so Bash performs parameter expansion before passing the generated program to Python. The values of `SECTIONS_JSON`, `VOICE`, `RATE`, and `OUTPUT_DIR` originate from command-line arguments and are inserted directly into Python string literals. Shell quoting around assignments such as `SECTIONS_JSON="${1:?...}"` only protects the shell assignment. It does not make those values safe for insertion into Python source code. An attacker-controlled value containing a quotation mark, newline, and Python statements can terminate the intended string literal and introduce arbitrary Python code. For example, a malicious argument can conceptually transform: ```python voice = "$VOICE" ``` into code shaped like: ```python voice = "" # Attacker-controlled Python statements execute here. x = "" ``` The injected statements execute under the same account and privileges as the user or automation invoking the skill. ### Attack Path 1. An attacker gains control over, or persuades a user or agent to use, one of the script arguments: - Sections ...[truncated 1251 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not interpolate shell values into executable Python source. 1. Quote the heredoc delimiter to disable shell expansion: ```bash python3 - "$SECTIONS_JSON" "$OUTPUT_DIR" "$VOICE" "$RATE" <<'PYEOF' import asyncio import json import sys from pathlib import Path import edge_tts sections_json = Path(sys.argv[1]) output_dir = Path(sys.argv[2]) voice = sys.argv[3] rate = sys.argv[4] with sections_json.open(encoding="utf-8") as f: segments = json.load(f) async def generate(): for i, text in enumerate(segments, 1): comm = edge_tts.Communicate(text, voice, rate=rate) fname = output_dir / f"seg{i:02d}.mp3" await comm.save(str(fname)) print(f"Generated {fname}") asyncio.run(generate()) PYEOF ``` 2. Validate `VOICE` against a strict allowlist of supported voice identifiers. 3. Validate `RATE` against the precise syntax and acceptable range expected by `edge-tts`, such as a signed integer percentage with bounded values. 4. Verify that the decoded JSON value is an array and that every element is a string. 5. Resolve and validate input and output paths if the script operates across a trust boundary. 6. Add regression tests using arguments containing quotes, newlines, backslashes, command substitutions, and Python syntax to confirm they remain inert data. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:91
Finding
Unpinned Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 91 **Vulnerability Type**: Mutable third-party dependency installation without version or integrity constraints **Risk Level**: Medium ### Vulnerable Code ```bash pip3 install edge-tts ``` ### Technical Analysis The installation instruction requests the latest package version available under the `edge-tts` package name at installation time. It provides neither an exact reviewed version nor a cryptographic hash. Transitive dependencies are also left unconstrained. Consequently, separate installations can resolve to different code. A compromised package release, compromised transitive dependency, package-index account takeover, or unexpected upstream update could introduce malicious or incompatible behavior after the skill itself has been reviewed. This is a supply-chain weakness rather than evidence that the current `edge-tts` package is malicious. ### Attack Path 1. A user follows the prerequisite instruction and runs the unpinned `pip3 install` command. 2. `pip` contacts its configured package index and resolves the current package and dependency versions. 3. A compromised or unexpectedly modified release is selected because no reviewed version or integrity hash is enforced. 4. Package installation or subsequent import executes affected package code. 5. That code operates with the permissions and data access of the installing or invoking user. The path becomes more severe if installation is performed globally, with elevated privileges, or in an environment containing sensitive credentials. ### Impact Assessment A compromised dependency could execute code during installation or when `generate-tts.sh` imports `edge_tts`. Potential impact includes: - Access to files and environment variables available to the user. - Theft of credentials or narration content. - Modification of generated artifacts. - Unauthorized network communication. - Compromise of the Python environment. - System- ...[truncated 167 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `edge-tts` to a specifically reviewed version rather than installing an unconstrained latest release: ```bash python3 -m pip install 'edge-tts==<reviewed-version>' ``` 2. Maintain a lock or requirements file that pins all transitive dependencies. 3. Generate and verify cryptographic hashes, for example with a requirements file installed using: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` 4. Install dependencies in a dedicated virtual environment rather than into the system Python environment. 5. Use the official package index explicitly and review any organization-specific index or mirror configuration. 6. Regularly scan pinned dependencies for known vulnerabilities and update them through a controlled review process. 7. Avoid recommending installation with `sudo` or another privileged account. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a full workflow for turning a silent screen recording into a narrated video, including video analysis, script writing, speech synthesis, and video/audio muxing. The supplied code chunk implements only one sub-step of that workflow: converting prewritten text segments from JSON into MP3 files and concatenating them. While Edge neural TTS use is consistent with the description, the code does not process video, inspect frames, create scripts, or output a narrated video. This is therefore a material description-to-behavior mismatch for the supplied code chunk.

Chaining Abuse

High
Category
Tool Misuse
Content
echo "file 'silence.mp3'" >> "$CONCAT_FILE"
done
# Remove trailing silence entry
sed -i.bak '$ d' "$CONCAT_FILE" && rm -f "${CONCAT_FILE}.bak"

# Concatenate
ffmpeg -y -f concat -safe 0 -i "$CONCAT_FILE" -c:a libmp3lame -q:a 2 \
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script sends narration text to Microsoft Edge TTS via the `edge_tts` library, which means potentially sensitive on-screen-derived content leaves the local environment. In a video narration skill, this is contextually important because screen recordings may contain confidential business data, credentials, or personal information, and the script provides no explicit warning, consent gate, or offline fallback at the point of transmission.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script invokes ffmpeg with the `-y` flag, which forces overwriting of the output file without prompting. If the caller supplies an existing output path, or if the default generated name already exists, prior data can be silently destroyed. In this skill context the issue is operational rather than code-execution related, but it can still cause unintended loss of user files or artifacts.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
The script defaults to the voice value en-US-GuyNeural, which imposes a specific language/locale choice unless the caller overrides it manually. The file does not indicate that this locale default is optional by policy, offer an explicit language choice, or justify the locale restriction as region-specific.

Static analysis

No suspicious patterns detected.