Back to skill

Security audit

doubao-tts-cn

Security checks for vulnerabilities and agentic risk

Overview

This text-to-speech skill mostly does what it claims, but users should review it because setup can expose the Volcengine access token and it installs unpinned Python packages into the active environment.

Install only if you are comfortable sending selected text or file contents to Volcengine for processing. Avoid putting the access token on the command line; prefer setting it through a protected environment or credential manager, rotate any token previously entered in shell history, and consider installing dependencies in a virtual environment after pinning or reviewing package versions.

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
requirements.txt:1
Finding
Unpinned dependencies are installed into the active Python environment<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-2`, `install.sh:137-140` **Vulnerability Type**: Unpinned third-party dependencies and mutable supply-chain inputs **Risk Level**: Medium ### Vulnerable Code ```text requests>=2.28.0 python-dotenv>=1.0.0 ``` ```bash # 4. 安装 Python 依赖 echo "" info "安装 Python 依赖..." python3 -m pip install -r "$SCRIPT_DIR/requirements.txt" --quiet success "Python 依赖安装完成" ``` ### Technical Analysis The dependency specifications use open-ended minimum-version constraints. Consequently, each installation may retrieve a different release, including future versions that were not reviewed with this Skill. No package hashes are supplied to verify the integrity of downloaded artifacts. The installation command also uses the active `python3` environment rather than creating a dedicated virtual environment. This can modify shared user or system Python environments, depending on how Python and pip are configured. This does not establish that the named packages are currently malicious. The vulnerability is that dependency resolution remains mutable and unauthenticated at the artifact level, expanding the impact of a compromised package release, package index, mirror, or dependency account. ### Attack Path 1. An attacker compromises a permitted package release, its publisher account, or the package index/mirror used by pip. 2. The attacker publishes a malicious version satisfying `requests>=2.28.0` or `python-dotenv>=1.0.0`. 3. A user runs `install.sh`. 4. Pip resolves and downloads the malicious or compromised version because no exact version or hash restricts selection. 5. Malicious package installation or import-time code executes with the privileges of the user running the installer. 6. That code can access files and environment variables available to the user, including the Skill's stored Volcengine credentials. ### Impact Assessment Successful exploitation can execute code with the invoking user's privil ...[truncated 565 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin each dependency to an exact, reviewed version rather than using open-ended minimum versions: ```text requests==<reviewed-version> python-dotenv==<reviewed-version> ``` 2. Generate and verify cryptographic hashes for all packages and transitive dependencies, then install with: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` 3. Create a dedicated virtual environment under a controlled Skill data directory instead of modifying the active Python environment. 4. Configure an explicit trusted package index and avoid unreviewed mirrors. 5. Add automated dependency vulnerability scanning and a controlled process for reviewing and updating pinned versions. 6. Advise users not to run the installer with elevated privileges. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
install.sh:42
Finding
Access token entry methods expose credentials through process arguments, shell history, and terminal echo<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:42-45`, `install.sh:117`; documented at `SKILL.md:36` and `README.md:30` **Vulnerability Type**: Insecure credential handling **Risk Level**: Medium ### Vulnerable Code The installer accepts the access token as a command-line argument: ```bash --access-token) ACCESS_TOKEN="$2" shift 2 ;; ``` The interactive path reads the token without disabling terminal echo: ```bash read -p " 请输入 VOLCENGINE_ACCESS_TOKEN: " ACCESS_TOKEN ``` The documented non-interactive invocation encourages placing the secret directly on the command line: ```bash bash {baseDir}/install.sh --app-id <your_app_id> --access-token <your_access_token> ``` ```bash bash install.sh --app-id <your_app_id> --access-token <your_access_token> ``` The installer subsequently stores the credential in a configuration file and correctly applies mode `600`: ```bash mkdir -p "$CONFIG_DIR" cat > "$ENV_FILE" << EOF VOLCENGINE_APP_ID=${APP_ID} VOLCENGINE_ACCESS_TOKEN=${ACCESS_TOKEN} EOF chmod 600 "$ENV_FILE" ``` The restrictive file mode mitigates post-installation disclosure but does not protect the token while it is entered or passed to the process. ### Technical Analysis Secrets supplied as command-line arguments can be retained in shell history and may be visible through process inspection, monitoring agents, audit logs, or diagnostic tooling. Although process visibility depends on operating-system configuration and timing, command-line arguments are not an appropriate secret transport mechanism. The interactive prompt uses ordinary `read` rather than silent input. The access token is therefore displayed on the terminal as it is typed and may be captured by terminal recording, screen sharing, shoulder surfing, or session logging. The token is legitimately required to authenticate requests to the declared Volcengine TTS service. The issue is not the use of the credential or its ...[truncated 1596 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove or deprecate `--access-token` so secrets are not accepted through process arguments. 2. For interactive installation, read the token silently: ```bash read -r -s -p "Enter VOLCENGINE_ACCESS_TOKEN: " ACCESS_TOKEN echo ``` 3. For automation, accept the token through a pre-set environment variable, protected file descriptor, or permission-restricted credential file rather than a command-line argument. 4. Update `README.md` and `SKILL.md` to remove examples that place access tokens directly in commands. 5. Preserve the existing `chmod 600` protection and additionally create the directory with restrictive permissions: ```bash umask 077 mkdir -p "$CONFIG_DIR" ``` 6. Validate that the configuration path is not a symbolic link before overwriting it, and use an atomic file-creation process. 7. Advise users who previously used the command-line option to remove affected shell-history entries and rotate any token that may have been exposed. ]]>
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (23)

Tainted flow: 'headers' from os.getenv (line 243, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
print(f"\n⏳ 正在提交合成任务...", flush=True)

    try:
        response = requests.post(SUBMIT_URL, headers=headers,
                                 data=json.dumps(payload), timeout=30)
    except requests.exceptions.RequestException as e:
        print(f"❌ 网络请求失败: {e}", flush=True)
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.getenv (line 243, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
payload = {"task_id": task_id}

    try:
        response = requests.post(QUERY_URL, headers=headers,
                                 data=json.dumps(payload), timeout=30)
        result = response.json()
        return result
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Credential Access

High
Category
Privilege Escalation
Content
### 1. 前置条件

- 在[火山引擎控制台](https://console.volcengine.com/)开通**语音合成**服务
- 创建应用,获取 `APP_ID` 和 `Access Token`

### 2. 安装
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
### 1. 前置条件

- 在[火山引擎控制台](https://console.volcengine.com/)开通**语音合成**服务
- 创建应用,获取 `APP_ID` 和 `Access Token`

### 2. 安装
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
### 1. 前置条件

- 在[火山引擎控制台](https://console.volcengine.com/)开通**语音合成**服务
- 创建应用,获取 `APP_ID` 和 `Access Token`

### 2. 安装
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
### 1. 前置条件

- 在[火山引擎控制台](https://console.volcengine.com/)开通**语音合成**服务
- 创建应用,获取 `APP_ID` 和 `Access Token`

### 2. 安装
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/doubao-tts"
ENV_FILE="$CONFIG_DIR/.env"

# 颜色输出
RED='\033[0;31m'
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
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/doubao-tts"
ENV_FILE="$CONFIG_DIR/.env"

# 颜色输出
RED='\033[0;31m'
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
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/doubao-tts"
ENV_FILE="$CONFIG_DIR/.env"

# 颜色输出
RED='\033[0;31m'
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README states that user-provided text or Markdown/TXT files are sent to Volcengine for synthesis, but it does not warn users that their content will be transmitted to a third-party cloud service. This can lead to accidental disclosure of sensitive data if users assume processing is local, especially for private documents or proprietary content.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares capabilities that imply shell, file, environment-variable, and network access, but it does not constrain them with an explicit permissions or allowed-tools scope. This increases the blast radius if the skill is invoked unexpectedly or modified later, because the runtime may grant broader access than users anticipate.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger description is broad enough to match common requests like reading text aloud or converting text to speech, which can cause the skill to activate in situations the user did not intend. Unintended invocation matters here because the skill can read files, use credentials, and send content to an external service.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation explains how to synthesize text and files but does not clearly warn that provided text or file contents will be transmitted to Volcengine for processing. This creates a privacy and data-handling risk, especially if users pass sensitive Markdown or local documents under the assumption processing is local.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The installer collects a sensitive access token and writes it to $HOME/.config/doubao-tts/.env in plain text without clearly warning the user that the secret will be stored on disk. If the host is compromised, backups are exposed, or file permissions are weakened/misapplied, the token can be recovered and abused to access the Volcengine TTS service.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The script reads VOLCENGINE_ACCESS_TOKEN using a normal read prompt, so the secret is echoed on screen as the user types. This exposes the token to shoulder-surfing, terminal recording, shared session capture, or shell session monitoring, which is especially risky in remote/admin environments.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
VOLCENGINE_APP_ID=${APP_ID}
VOLCENGINE_ACCESS_TOKEN=${ACCESS_TOKEN}
EOF
    chmod 600 "$ENV_FILE"
    success "凭证已保存到: $ENV_FILE"
fi
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
All user-facing instructions in the file are presented in Chinese, and there is no indication that the skill is intentionally limited to Chinese-speaking users or a China-specific deployment context. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
All prompts, help text, and status messages are presented in Chinese, which imposes a language choice on users without opt-in. Under the stated policy, forcing a specific language without user choice is a natural-language policy concern unless clearly documented as region-specific.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
python-dotenv>=1.0.0
Confidence
98% confidence
Finding
The dependency is specified with a lower-bound range instead of an exact version, which makes builds non-reproducible and can pull in unexpected or vulnerable releases over time. In a skill that may be deployed in different environments, this increases supply-chain risk and makes it hard to verify whether a safe version of requests is actually installed.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
The manifest references requests without pinning, and requests has multiple historical advisories; because the exact installed version is unknown, the environment could resolve to an affected release. For a network-facing TTS skill that likely makes outbound API calls, flaws in HTTP handling or credential management can be relevant if a vulnerable version is installed.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
python-dotenv>=1.0.0
Confidence
97% confidence
Finding
python-dotenv is also unpinned, so installations may resolve to different versions depending on time and environment. This weakens reproducibility and can expose the skill to newly introduced or already-known vulnerable package versions without any manifest change.

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
87% confidence
Finding
python-dotenv has known advisories, and because the dependency is not pinned there is no assurance that deployment will avoid affected versions. While the risk depends on how dotenv file writing/loading is used elsewhere in the skill, leaving the version unconstrained creates unnecessary exposure to package-level vulnerabilities.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The module docstring, CLI description, help text, and user-facing messages are entirely in Chinese, with no indication that other languages are supported or that the locale restriction is intentional. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

Static analysis

No suspicious patterns detected.