Back to skill

Security audit

doubao-tts

Security checks for vulnerabilities and agentic risk

Overview

This cloud text-to-speech skill is mostly purpose-aligned, but it needs review because it can upload user text externally and its save/playback code contains unsafe path handling that can become command execution.

Review before installing. Use this only for text you are comfortable sending to Volcengine/Bytedance, protect the access token file with restrictive permissions or a secret manager, avoid the documented global unpinned install flow, and do not use arbitrary save paths until the PowerShell playback and temporary-file handling are fixed.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:272
Finding
PowerShell Command Injection Through a User-Controlled Output Path<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:272`, `SKILL.md:288-289` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```bash output_file="${save_path:-/tmp/doubao_tts_$(date +%s).mp3}" ``` ```bash elif command -v powershell &> /dev/null; then powershell -c "(New-Object Media.SoundPlayer '$output_file').PlaySync()" ``` ### Technical Analysis The output path can originate from the user-controlled `save_path` value. Although the shell quotes `"$output_file"` when expanding it, its value is subsequently embedded inside a dynamically constructed PowerShell program. The PowerShell command encloses the path in single quotes without escaping embedded single quotes or other PowerShell syntax. A crafted path can therefore terminate the string literal and append arbitrary PowerShell statements. Shell quoting does not protect values after they are inserted into source code interpreted by another command processor. This is a second-order command-injection vulnerability. ### Attack Path 1. An attacker supplies a TTS request with a malicious save path. 2. The path is assigned to `save_path` and then to `output_file`. 3. The Skill successfully requests or processes TTS audio. 4. On a system where PowerShell is selected as the available player, `output_file` is interpolated into the `powershell -c` source string. 5. An embedded single quote terminates the intended path literal. 6. PowerShell parses and executes the attacker's appended statements with the privileges of the Agent process. For example, a path shaped like `'; <attacker-command>; #'` can alter the resulting PowerShell program rather than being treated solely as a filename. ### Impact Assessment Successful exploitation permits arbitrary PowerShell command execution with the same operating-system privileges as the OpenClaw or Agent process. Depending on those privileges, an attacker could read or modify user files, access locally available cred ...[truncated 248 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not interpolate filenames into dynamically evaluated PowerShell source. - Pass the path as a positional argument to a fixed PowerShell script and access it through PowerShell's argument array. - Prefer an invocation pattern that keeps code and data separate. - Validate that the requested destination is within an explicitly permitted directory. - Canonicalize paths before use and reject unexpected characters, alternate data streams, and unsafe path forms. - Use native platform APIs or a player command that accepts the filename as a normal argument without evaluating it as source code. - Add regression tests using paths containing single quotes, semicolons, newlines, and PowerShell metacharacters. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:272
Finding
Predictable Temporary Audio Files Allow Symlink-Based File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:272-273`, `SKILL.md:359-360` **Vulnerability Type**: Insecure temporary-file creation and symlink overwrite **Risk Level**: Medium ### Vulnerable Code ```bash output_file="${save_path:-/tmp/doubao_tts_$(date +%s).mp3}" echo "$audio_base64" | base64 -d > "$output_file" ``` The complete example uses a similarly predictable process-ID-based name: ```bash output_file="${save_path:-/tmp/doubao_tts_$$.mp3}" echo "$audio_base64" | base64 -d > "$output_file" ``` ### Technical Analysis The Skill constructs files directly in the shared `/tmp` directory using either the current Unix timestamp or shell process ID. Both values are predictable or discoverable by other local users. The shell redirection operator opens the destination with truncation and follows symbolic links. The code does not create the file atomically, verify ownership, reject symbolic links, or reserve a private temporary directory before writing. Consequently, another local process can create a symbolic link at the anticipated path before the Skill performs the redirection. The decoded audio is then written through that link to a different file. ### Attack Path 1. A local attacker predicts the next timestamp-based filename or observes/predicts the relevant process ID. 2. The attacker creates that path in `/tmp` as a symbolic link to a target file writable by the Agent process. 3. The user or Agent invokes the TTS Skill. 4. The Skill selects the predictable path without verifying whether it already exists or is a symbolic link. 5. Shell redirection follows the link and truncates the target. 6. The decoded MP3 content overwrites the target file. ### Impact Assessment An attacker can overwrite or corrupt files writable by the account running the Skill. Potential targets include user configuration, shell initialization files, application state, and other writable data. The effective scope is constrained by the privileges of the Age ...[truncated 215 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create a private temporary directory with `mktemp -d` and restrictive permissions. - Generate the audio file inside that directory with `mktemp` rather than constructing a timestamp- or PID-based name. - Create files atomically and fail if a destination already exists. - Reject symbolic links and verify the destination's ownership and file type before use. - Set a restrictive `umask`, such as `077`, before creating temporary audio files. - Register cleanup logic with `trap` so temporary files and directories are removed after playback or on failure. - If a user supplies a save path, canonicalize it and apply an explicit overwrite policy rather than silently truncating an existing file. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:8
Finding
Unpinned Global Installation From an Unspecified Third-Party Source<![CDATA[ ## Vulnerability Details **File Location**: `README.md:8-10` **Vulnerability Type**: Insecure dependency and installation guidance **Risk Level**: Medium ### Vulnerable Code ```bash npx skills add <your-username>/doubao-tts -g ``` ### Technical Analysis The installation instruction invokes an `npx`-resolved tool, leaves the repository owner unspecified, does not pin the Skill to an immutable version or commit, and requests global installation. As written, users must substitute a repository identity themselves. A mistaken, misleading, or attacker-controlled repository can therefore be selected. Because no immutable revision or integrity value is provided, the installed contents can also change after review. Global installation broadens the persistence and impact of a compromised package compared with a project-local installation. ### Attack Path 1. A user follows the documented installation procedure. 2. The user substitutes an incorrect or attacker-controlled repository for the placeholder. 3. `npx` resolves the installation tooling and retrieves mutable Skill content from the selected source. 4. The globally installed content differs from the audited project or contains malicious behavior. 5. That content executes when installed or when the Skill is subsequently invoked. ### Impact Assessment A compromised source can introduce arbitrary malicious Skill instructions or executable content into the user's environment. The resulting privileges are generally those of the user running `npx`; impact may be greater if the command is run from an elevated shell. Possible consequences include credential theft, unauthorized file access, command execution, malicious Agent behavior, and persistent global installation of untrusted components. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the repository placeholder with the verified official publisher and repository. - Pin installation to an immutable release, tag backed by a verified commit, or explicit commit hash. - Publish and document an integrity checksum or signed release verification process. - Avoid global installation unless it is operationally necessary; prefer a scoped, local installation. - Document how users can inspect the retrieved Skill before activation. - Pin or otherwise verify the `npx` installation tool rather than relying on an unspecified mutable resolution. - Protect the publishing account and release process with signed commits, protected tags, and multi-factor authentication. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (19)

Credential Access

High
Category
Privilege Escalation
Content
```json
{
  "appid": "你的 AppID",
  "access_token": "你的 Access Token",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
Confidence
88% confidence
Finding
The README tells users to place the `access_token` in a plaintext JSON config file under the home directory, with no warning about file permissions or safer secret storage. This increases the risk of local credential exposure through backups, accidental commits, shared machines, or overly permissive filesystem access.

Credential Access

High
Category
Privilege Escalation
Content
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
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
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
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
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
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
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
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
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
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
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
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
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
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
{
  "appid": "你的 AppID(从火山引擎控制台获取)",
  "access_token": "你的 Access Token(从火山引擎控制台获取)",
  "cluster": "volcano_tts",
  "voice_type": "BV700_streaming",
  "emotion": "pleased"
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation instructs users to store an `access_token` in a local config file and use a cloud TTS provider, but it does not warn about secret handling, file permissions, or that text content will be transmitted to an external network service. This can lead users to expose credentials or unknowingly send sensitive text off-device.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger examples such as “朗读”, “读出来”, and “播放这段” are broad, natural-language phrases likely to overlap with ordinary conversation. In an agent environment, overly generic triggers can cause unintended invocation of the skill and accidental transmission of user-provided text to the external TTS service.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger set includes very generic phrases such as '朗读', '读出来', and '播放这段', which are common in ordinary conversation and can cause the skill to activate unexpectedly. In this skill, accidental activation is more concerning because it sends user-provided text to an external third-party TTS service, creating an avoidable privacy and consent risk.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill description presents the feature as local text-to-speech behavior but does not disclose that input text is uploaded to Volcengine/Bytedance for synthesis. This omission can cause users to unknowingly send sensitive text, credentials, private messages, or regulated data to an external provider.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
api_url="https://openspeech.bytedance.com/api/v1/tts"

response=$(curl -s -X POST "$api_url" \
  -H "Authorization: Bearer;$access_token" \
  -H "Content-Type: application/json" \
  -d "$json_payload")
Confidence
97% confidence
Finding
This code sends the full input text and service metadata to an external API endpoint over the network. In the context of a TTS skill this transmission is expected, but it is still security-relevant because any text the user asks to read aloud leaves the local environment and is exposed to a third party.

External Transmission

Medium
Category
Data Exfiltration
Content
)

# 发送请求
response=$(curl -s -X POST "https://openspeech.bytedance.com/api/v1/tts" \
  -H "Authorization: Bearer;$access_token" \
  -H "Content-Type: application/json" \
  -d "$json_payload")
Confidence
97% confidence
Finding
The example script also transmits user input and configuration-derived identifiers to the remote Bytedance TTS service. Although this is functionally necessary for cloud TTS, it remains a true data-exposure risk if the skill is triggered on sensitive text or used without adequate notice.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list contains broad, natural-language phrases such as '朗读', '读出来', and '播放这段' that are likely to appear in normal conversation and overlap with many unrelated user intents. This increases the chance of accidental or ambiguous activation, which can cause the wrong skill to run, potentially sending unintended text to an external TTS service or producing unexpected audio output.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
整个 README 仅以中文描述安装、配置和触发方式,未说明该技能是否仅面向中文用户,也未提供语言/locale 选择。若组织要求避免未经用户同意强制特定语言,这种单一语言说明可能构成自然语言策略问题。

Overly Broad Trigger

Low
Category
Trigger Abuse
Confidence
95% confidence
Finding
The trigger '朗读' is extremely short and generic, making accidental invocation likely during routine conversation. In this skill that matters because activation can lead to unintentional network transmission of user text to a third-party TTS provider.

Static analysis

No suspicious patterns detected.