Back to skill

Security audit

Snowvoice Tts

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed local Chinese text-to-speech helper, but its setup runs an unpinned remote installer with broad user-level command authority.

Review before installing. Only run setup if you trust the SnowVoice upstream repository and are comfortable letting its current install.sh execute with your user account permissions. Prefer a pinned, verified release or inspect the cloned installer first; do not allow automatic setup from a casual text-to-speech request.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/init.py:20
Finding
Unpinned Remote Repository Is Retrieved and Executed During Setup<![CDATA[ ## Vulnerability Details **File Location**: `scripts/init.py:20`, `scripts/init.py:111-135`; setup is recommended in `SKILL.md:25-37` **Vulnerability Type**: Unverified remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```python SNOWVOICE_REPO = "https://github.com/webkubor/snowvoice-studio.git" ``` ```python # 2. 克隆仓库 if install_path.exists(): result["steps"].append(f"⏭ 目录已存在: {install_path}") else: code, _, err = run_cmd( ["git", "clone", SNOWVOICE_REPO, str(install_path)] ) if code != 0: result["message"] = f"克隆失败: {err}" return result result["steps"].append(f"✓ 克隆仓库完成") # 3. 运行 install.sh(会创建 venv、安装依赖、下载 Base 模型) install_script = install_path / "install.sh" if not install_script.exists(): result["message"] = f"install.sh 不存在: {install_script}" return result run_cmd(["chmod", "+x", str(install_script)]) # install.sh 会下载 Base-1.7B 模型 code, out, err = run_cmd( ["bash", str(install_script)], cwd=str(install_path), timeout=600, ) ``` ### Technical Analysis The setup process clones the mutable default branch of an external GitHub repository and immediately executes its `install.sh` script. It does not pin a reviewed commit or release, verify a cryptographic digest or signature, or inspect the retrieved script before execution. Consequently, the effective executable payload can change after this Skill has been audited. The trust check for an existing installation directory is also insufficient. When `~/.snowvoice-studio` already exists, cloning is skipped and the local `install.sh` is executed based only on its presence. The code does not verify that the directory is a Git repository from the expected upstream, that its revision is approved, or that the installer has the expected digest. Using a subprocess argument array prevents shell metacharacters in the repository URL from being interpreted locally, but it does not mitigate execution of malicious c ...[truncated 1836 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the upstream source to an immutable, reviewed commit hash rather than cloning and executing the mutable default branch. 2. Distribute an expected SHA-256 or stronger digest for `install.sh` and verify it before execution. Prefer a cryptographically signed release with verification against a pinned maintainer key. 3. Clone without executing code, explicitly check out the approved commit, and verify that `HEAD` exactly matches it: ```bash git clone --no-checkout <repository> <destination> git -C <destination> checkout --detach <approved-commit> test "$(git -C <destination> rev-parse HEAD)" = "<approved-commit>" ``` 4. Do not trust an installation merely because its directory and files exist. For pre-existing directories, validate the repository origin, exact commit, expected file digests, ownership, and permissions. Abort on any mismatch. 5. Vendor and audit the required installation logic where practical, or replace the general-purpose shell installer with explicit installation steps using version-pinned dependencies and hash verification. 6. Execute installation with the least privileges possible and clearly require user confirmation before running remotely sourced code. 7. Treat installer failure and timeout as failure. The current logic may report success after a nonzero installer result or timeout, which can leave an unverified partial installation available for later use. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared purpose presents the skill as a local TTS utility, but the documented behavior also includes repository cloning, environment setup, dependency installation, and multi-gigabyte model downloads. This mismatch is dangerous because users or orchestrators may approve the skill expecting simple audio generation while it actually performs network access and system modifications with a much larger trust and attack surface.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill documents shell-capable behavior such as running Python commands, installation scripts, cloning a repository, and downloading models, but it declares no explicit tool scope or permission boundaries. That creates an authorization gap where an agent may invoke shell actions without a clear least-privilege contract, increasing the risk of unexpected command execution or overbroad access.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The trigger phrases are very broad, everyday requests like converting text to speech or reading text aloud, which can cause the skill to activate in routine conversations without strong user intent to run this specific local tool. In this skill's context, unintended activation is more dangerous because activation can lead not only to synthesis but also to setup checks, installation guidance, shell execution, and potential downloads.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The module docstring presents the skill description and operating instructions entirely in Chinese, with no indication that language is selectable or user-driven. This can violate a language/locale policy when a skill implicitly forces one language without offering opt-in or alternatives.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_cmd(cmd, **kwargs):
    """运行命令,返回 (returncode, stdout, stderr)"""
    result = subprocess.run(cmd, capture_output=True, text=True, **kwargs)
    return result.returncode, result.stdout, result.stderr
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The initializer clones a remote GitHub repository and then executes its install.sh locally, which is effectively remote code execution at install time. In an agent skill context, this is especially dangerous because a user invoking a TTS capability would not reasonably expect arbitrary third-party code fetch-and-execute behavior, and the script performs no pinning, signature verification, or content validation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code's natural-language interface, usage text, and descriptive strings are presented only in Chinese, which effectively constrains the skill to a specific language. The file does not indicate that the language restriction is optional, user-selectable, or justified as a region-specific tool.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = [python, "-m", "cli.app"] + args
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The description repeatedly frames the skill as a Chinese-only tool ('本地中文语音合成工具', '本地中文语音合成 Skill') without indicating that users may choose another language or that the restriction is an intentional, justified locale constraint. Under the policy, language constraints should either be optional for the user or clearly documented as region- or compliance-specific.

Static analysis

No suspicious patterns detected.