Back to skill

Security audit

TencentCloud TTS

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Tencent Cloud text-to-speech wrapper, but it needs review because it can overwrite arbitrary local files and may print parts of configured credentials.

Install only if you are comfortable sending TTS text to Tencent Cloud and using Tencent Cloud API credentials. Avoid submitting secrets, personal data, or regulated content. Use a dedicated low-privilege Tencent key, do not run the config helper in logs that others can read, and restrict output filenames to a safe audio directory to avoid overwriting local files.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/tencent_tts.py:115
Finding
Unrestricted Output Path Allows Arbitrary File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/tencent_tts.py`, lines 115-118 and 175-176 **Vulnerability Type**: Unrestricted file path and unsafe overwrite **Risk Level**: Medium ### Vulnerable Code ```python def synthesize(self, text, voice_type=101001, codec="mp3", output_file="output.mp3"): ``` ```python audio_bytes = base64.b64decode(audio_data) with open(output_file, "wb") as f: f.write(audio_bytes) ``` ### Technical Analysis The `output_file` parameter is used directly as a filesystem path without validating, normalizing, or restricting it to an approved output directory. Python's `"wb"` mode creates a missing file or truncates an existing file before writing the audio response. Consequently, a caller that controls `output_file` can provide an absolute path or a path containing traversal sequences such as `../`. The write occurs after a successful Tencent Cloud response, so exploitation requires valid credentials, network access, and a successful synthesis request. The attacker cannot use this flaw to choose arbitrary file contents because the written bytes are the audio returned by Tencent Cloud. However, the attacker can still destroy or corrupt existing files by replacing them with audio data. ### Attack Path 1. An attacker gains influence over the `output_file` argument through an application or agent that exposes the Skill. 2. The attacker supplies an absolute or traversal path, such as `../../application/config.py`. 3. The Skill submits an otherwise valid synthesis request to Tencent Cloud. 4. Tencent Cloud returns a successful response containing Base64-encoded audio. 5. The Skill opens the attacker-selected path using `"wb"`. 6. Any existing target file is truncated and replaced with the decoded audio. ### Impact Assessment The vulnerability permits file creation, truncation, and overwrite with the privileges of the process running the Skill. Potential consequenc ...[truncated 448 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Define a dedicated audio output directory controlled by the application. - Reject absolute paths and parent-directory traversal components. - Resolve the requested path and verify that it remains beneath the approved directory: ```python from pathlib import Path output_dir = Path("./audio_output").resolve() output_dir.mkdir(mode=0o700, parents=True, exist_ok=True) requested_name = Path(output_file) if requested_name.is_absolute(): raise ValueError("Absolute output paths are not allowed") resolved_output = (output_dir / requested_name).resolve() if output_dir not in resolved_output.parents: raise ValueError("Output path escapes the approved directory") ``` - Accept a filename rather than an unrestricted path when directory selection is unnecessary. - Use exclusive creation mode (`"xb"`) by default to prevent silent replacement of existing files. - If overwrite functionality is required, make it an explicit option and obtain confirmation before replacing a file. - Apply restrictive file permissions and run the Skill under a least-privileged operating-system account. - Add tests covering absolute paths, `../` traversal, symlink-based escapes, and attempts to overwrite existing files. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
config/config_template.py:54
Finding
Credential Fragments Are Exposed in Configuration Status Output<![CDATA[ ## Vulnerability Details **File Location**: `config/config_template.py`, lines 54-59 and 118-120 **Vulnerability Type**: Sensitive information exposure through console output **Risk Level**: Low ### Vulnerable Code ```python # Check all configuration items for config_name in cls.REQUIRED_CONFIGS + list(cls.OPTIONAL_CONFIGS.keys()): value = os.getenv(config_name) if value: status["available_configs"][config_name] = value[:10] + "..." if len(value) > 10 else value else: status["available_configs"][config_name] = "Not set" ``` ```python print("Current configuration status:") for config_name, value in status["available_configs"].items(): icon = "configured" if value != "Not set" else "missing" print(f" {icon} {config_name}: {value}") ``` The source file uses localized display strings, but the security-relevant behavior shown above is unchanged: environment-variable values are copied into the status report and printed. ### Technical Analysis `get_config_status()` processes both required credentials and optional configuration values, including: - `TENCENTCLOUD_SECRET_ID` - `TENCENTCLOUD_SECRET_KEY` - `TENCENTCLOUD_TOKEN` For values longer than ten characters, the first ten characters are retained and displayed. Values of ten characters or fewer are displayed in full. `setup_environment()` then prints these values to standard output. Console output may be retained in CI logs, terminal recordings, support bundles, shell transcripts, or centralized logging systems. Secret prefixes reduce credential confidentiality, while short secrets or tokens may be disclosed completely. ### Attack Path 1. A user configures Tencent Cloud credentials in environment variables. 2. The user runs `config/config_template.py` or otherwise calls `setup_environment()`. 3. `get_config_status()` reads the credentials from the environment. 4. The first ten characters—or the complete value when short—are stored in `available_configs`. 5. ` ...[truncated 838 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never place Secret Key or temporary-token contents in status reports. - Report only whether each sensitive variable is configured: ```python sensitive_names = { "TENCENTCLOUD_SECRET_ID", "TENCENTCLOUD_SECRET_KEY", "TENCENTCLOUD_TOKEN", } for config_name in cls.REQUIRED_CONFIGS + list(cls.OPTIONAL_CONFIGS): value = os.getenv(config_name) if config_name in sensitive_names: status["available_configs"][config_name] = "Configured" if value else "Not set" else: status["available_configs"][config_name] = value if value else "Not set" ``` - Fully mask `TENCENTCLOUD_SECRET_KEY` and `TENCENTCLOUD_TOKEN`. - If operators must distinguish credentials, display a non-reversible fingerprint rather than a prefix. - Avoid logging environment-derived secrets at debug or error levels. - Review existing CI logs, support bundles, and terminal captures for prior exposure, and rotate credentials if sensitive values may have been disclosed. - Add automated tests asserting that known credential strings and their prefixes never appear in generated status output. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (23)

Credential Access

High
Category
Privilege Escalation
Content
def generate_env_template(cls) -> str:
        """生成环境变量模板文件内容"""
        template = """# 腾讯云语音合成服务环境配置
# 请将本文件保存为 .env 文件,并根据实际情况修改配置值

# ===== 必需配置项 =====
# 腾讯云API密钥 - 请从腾讯云控制台获取
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def generate_env_template(cls) -> str:
        """生成环境变量模板文件内容"""
        template = """# 腾讯云语音合成服务环境配置
# 请将本文件保存为 .env 文件,并根据实际情况修改配置值

# ===== 必需配置项 =====
# 腾讯云API密钥 - 请从腾讯云控制台获取
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def generate_env_template(cls) -> str:
        """生成环境变量模板文件内容"""
        template = """# 腾讯云语音合成服务环境配置
# 请将本文件保存为 .env 文件,并根据实际情况修改配置值

# ===== 必需配置项 =====
# 腾讯云API密钥 - 请从腾讯云控制台获取
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
print(f"✅ 已生成环境变量模板: {env_file_path}")
    print("💡 使用方法:")
    print("   1. 复制 .env.template 为 .env")
    print("   2. 编辑 .env 文件,填入实际的API密钥")
    print("   3. 运行: source .env")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
print(f"✅ 已生成环境变量模板: {env_file_path}")
    print("💡 使用方法:")
    print("   1. 复制 .env.template 为 .env")
    print("   2. 编辑 .env 文件,填入实际的API密钥")
    print("   3. 运行: source .env")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README shows direct use of the synthesize API but does not clearly warn that input text is transmitted to Tencent Cloud for remote processing. Users may unknowingly send sensitive, regulated, or confidential content to a third-party service, creating privacy, compliance, and data-handling risks. In a TTS skill, this omission is more dangerous because the core function necessarily processes arbitrary user text, which often includes personal or proprietary content.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill documentation indicates capabilities involving environment variable access and file writing, but it does not declare any explicit tool scope or permission boundaries. This creates a transparency and least-privilege problem: an agent may invoke the skill without clear constraints, increasing the chance of unintended secret exposure or unauthorized file creation in broader execution contexts.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The trigger language is broad enough to match many common requests related to speech, TTS, or audio file generation, which can cause over-selection of this skill in situations where a more appropriate or safer tool should be used. In an agentic system, overly broad activation conditions can expand the skill's reach and lead to unnecessary use of environment-backed credentials and file output behavior.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
SQP-3 applies to all file types and covers language/locale policy violations in natural-language content, including code docstrings and printed strings. This file consistently presents setup guidance in Chinese only and does not provide any opt-in, alternative language, or stated region-specific justification.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
This JSON file contains user-facing prompt text exclusively in Chinese across multiple eval cases. Because the skill does not indicate that it is intentionally restricted to Chinese users or provide any opt-in or language-choice mechanism, it may violate language/locale policy requirements.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code presents its description and runtime user-facing output primarily in Chinese, while the file itself does not state that it is intended only for a Chinese-speaking or region-specific audience. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This Python file contains user-facing documentation and command-line messages entirely in Chinese, including the module description and runtime prompts. Under the policy rule for language/locale, forcing a specific language without user opt-in is a natural-language policy violation unless the tool is clearly documented as region-specific.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The file's natural-language comments are entirely in Chinese, including usage notes and warnings, without any indication that the skill is region-specific or that users may choose another language. Under the policy for all file types, this can be a language/locale constraint that is not documented as optional or justified.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 这些包不是必需的,但可以增强功能

# 测试依赖(用于开发和测试)
pytest>=6.0.0
pytest-cov>=2.0.0

# 开发工具
Confidence
89% confidence
Finding
Using an unpinned dependency range like pytest>=6.0.0 makes builds non-reproducible and can silently pull in vulnerable or breaking future releases. In this file the package is only listed as a test dependency, so the operational risk to the TTS skill is limited, but it still weakens supply-chain hygiene.

Unverifiable Dependency: pytest has 2 known advisory(ies) (CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
83% confidence
Finding
The manifest does not pin pytest, so it is impossible to determine whether installations will resolve to a version affected by the cited advisory. In this skill the package is only used for testing, which lowers runtime impact, but ambiguous vulnerable-version exposure is still a legitimate supply-chain risk.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 测试依赖(用于开发和测试)
pytest>=6.0.0
pytest-cov>=2.0.0

# 开发工具
black>=20.0.0
Confidence
88% confidence
Finding
An unpinned pytest-cov dependency allows uncontrolled version resolution, which can introduce vulnerable or incompatible releases into CI or development environments. Although this is not part of the core runtime path for the TTS skill, it still creates avoidable supply-chain uncertainty.

Unpinned Dependencies

Low
Category
Supply Chain
Content
pytest-cov>=2.0.0

# 开发工具
black>=20.0.0
flake8>=3.8.0
mypy>=0.800
Confidence
93% confidence
Finding
black>=20.0.0 permits installation of arbitrary future versions and also leaves open the possibility of resolving to older vulnerable versions depending on environment state. Because Black has known advisories and is commonly executed on developer machines and CI, an unsafe version could affect local files or disrupt pipelines even though it is a dev tool rather than the TTS runtime itself.

Unverifiable Dependency: black has 5 known advisory(ies) (CVE-2026-32274 (Black: Arbitrary file writes from unsanitized user input in cache file name); CVE-2024-21503 (Black vulnerable to Regular Expression Denial of Service (ReDoS)); CVE-2024-21503 (Versions of the package black before 24.3.0 are vulnerable to Regular Expression) +2 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding
Because black is unpinned and has multiple known advisories, the project cannot verify whether a safe version will be installed. Since Black runs in developer and CI contexts and some advisories involve file-write or ReDoS behavior, a vulnerable resolved version could have meaningful impact even if it is not part of the production TTS execution path.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 开发工具
black>=20.0.0
flake8>=3.8.0
mypy>=0.800

# 文档生成
Confidence
86% confidence
Finding
flake8>=3.8.0 is unpinned, so builds may consume unexpected versions with different behavior or future vulnerabilities. This primarily affects development and CI rather than production execution of the TTS skill, but it remains a supply-chain hardening issue.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 开发工具
black>=20.0.0
flake8>=3.8.0
mypy>=0.800

# 文档生成
sphinx>=3.0.0
Confidence
86% confidence
Finding
mypy>=0.800 leaves dependency resolution open-ended, reducing reproducibility and increasing the chance of pulling in compromised or breaking releases. In this context it is a development-time risk rather than a direct runtime issue for the TTS functionality.

Unpinned Dependencies

Low
Category
Supply Chain
Content
mypy>=0.800

# 文档生成
sphinx>=3.0.0
sphinx-rtd-theme>=0.5.0

# 注意:本skill包主要使用Python标准库
Confidence
87% confidence
Finding
sphinx>=3.0.0 allows uncontrolled version drift in documentation tooling, which can expose documentation build environments to vulnerable releases or inconsistent behavior. This is not directly exploitable through the TTS runtime, but it is still poor dependency hygiene.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 文档生成
sphinx>=3.0.0
sphinx-rtd-theme>=0.5.0

# 注意:本skill包主要使用Python标准库
# 如果需要额外功能,可以按需安装上述依赖
Confidence
87% confidence
Finding
sphinx-rtd-theme>=0.5.0 is unpinned and can pull in unreviewed versions during documentation builds. The risk is limited to developer/docs environments, but it still introduces unnecessary supply-chain variability.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This Python file contains user-facing natural-language descriptions and runtime messages in Chinese, starting with the module docstring and continuing throughout the script. Because the skill does not offer any language selection or document that it is intentionally region- or locale-specific, it may violate a language/locale policy requiring user choice.

Static analysis

No suspicious patterns detected.