Back to skill

Security audit

Minimax Tts Cn

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but its Telegram delivery path handles bot credentials unsafely enough that users should review it before installing.

Install only if you are comfortable sending TTS text to MiniMax and, in default wrapper mode, sending generated audio to the configured Telegram chat. Keep the .env file private, use a low-privilege Telegram bot, prefer --generate-only when you do not intend to send messages, and consider fixing the curl token exposure and .env allowlist before production use.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/tts-xiaoye.sh:173
Finding
Telegram Bot Token Exposed Through Process Command-Line Arguments## Vulnerability Details **File Location**: `scripts/tts-xiaoye.sh`, lines 173-181 **Vulnerability Type**: Credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash if [[ -n "$CAPTION" ]]; then RESPONSE=$(curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendVoice" \ -F "chat_id=${TARGET}" \ -F "voice=@${AUDIO_FILE}" \ -F "caption=${CAPTION}") else RESPONSE=$(curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendVoice" \ -F "chat_id=${TARGET}" \ -F "voice=@${AUDIO_FILE}") fi ``` ### Technical Analysis The Telegram bot token is interpolated directly into the URL passed as a command-line argument to `curl`. While the process is running, the complete URL can be exposed through process-inspection mechanisms such as `ps`, process-monitoring utilities, or `/proc/<pid>/cmdline` on systems where another local account or process has sufficient inspection rights. HTTPS protects the token in transit but does not prevent local disclosure from the command line. The network transmission itself is necessary for the declared Telegram delivery feature; placing the credential in an observable process argument is not necessary. ### Attack Path 1. A user invokes the Skill in its default Telegram delivery mode. 2. The wrapper starts `curl` with the Telegram bot token embedded in its URL. 3. A local attacker or compromised monitoring process repeatedly inspects process command lines while the request is active. 4. The attacker extracts the token from the `/bot<token>/sendVoice` URL. 5. The attacker uses the token to invoke Telegram Bot API methods as the affected bot. Exploitation requires local process-observation access and successful timing while `curl` is running. ### Impact Assessment Disclosure grants the attacker the API authority associated with the Telegram bot token. Depending on the bot's configuration and Telegram per ...[truncated 267 chars]
Remediation
## Remediation Suggestions - Do not include secrets in process command-line arguments. - Use an HTTP client implementation that constructs the Telegram URL internally after startup, such as the existing Python `requests` dependency. - If `curl` must be retained, supply sensitive configuration through a protected standard-input configuration rather than an argument, while ensuring error output cannot disclose the URL. - Restrict the `.env` file to the owning account, for example with mode `0600`. - Run the Skill under a dedicated, least-privileged account and restrict cross-process inspection where the operating system supports it. - Rotate the Telegram bot token if command-line exposure may already have occurred.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/tts-xiaoye.sh:27
Finding
Unrestricted Environment Variable Export from the Skill Configuration File## Vulnerability Details **File Location**: `scripts/tts-xiaoye.sh`, lines 27-34 **Vulnerability Type**: Unsafe configuration parsing and environment manipulation **Risk Level**: Low ### Vulnerable Code ```bash if [[ -f "$ENV_FILE" ]]; then while IFS='=' read -r key value; do [[ -z "$key" || "$key" == \#* ]] && continue value=$(echo "$value" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//") [[ -n "$value" ]] && export "$key=$value" done < "$ENV_FILE" fi ``` ### Technical Analysis The loader exports every nonempty key found in `.env`, although the Skill documents only `MINIMAX_API_KEY`, `TELEGRAM_BOT_TOKEN`, `TELEGRAM_TARGET`, and `TTS_MODEL`. An attacker who can modify this configuration can introduce variables that alter child-process behavior. Examples include Python module-search variables, proxy variables that redirect outbound requests, certificate-related settings, or other runtime-specific environment controls. The shell correctly quotes the assignment, so this is not direct shell command injection; the risk arises from unrestricted control over the environment inherited by `python3`, `curl`, and FFmpeg. This issue primarily represents a defense-in-depth failure because modifying the Skill's `.env` file generally already requires access to the user's workspace. ### Attack Path 1. An attacker obtains write access to the Skill's `.env` file through another vulnerability, an unsafe deployment process, or overly broad filesystem permissions. 2. The attacker adds an undocumented environment variable that influences one of the invoked child programs. 3. A user runs the TTS wrapper. 4. The wrapper exports the attacker-controlled variable without validation. 5. The affected child process inherits it and may load attacker-controlled resources, redirect traffic, or otherwise operate under altered runtime settings. The precis ...[truncated 496 chars]
Remediation
## Remediation Suggestions - Replace unrestricted export with an explicit allowlist containing only: - `MINIMAX_API_KEY` - `TELEGRAM_BOT_TOKEN` - `TELEGRAM_TARGET` - `TTS_MODEL` - Reject malformed keys and report unknown keys rather than silently exporting them. - Validate `TTS_MODEL` against supported model identifiers. - Enforce restrictive ownership and permissions on `.env`, preferably mode `0600`. - Consider using the Python configuration loader consistently instead of maintaining separate shell and Python parsers. - Launch child processes with a minimized environment where practical.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/tts-xiaoye.sh:173
Finding
Telegram API Failures Are Reported as Successful Delivery## Vulnerability Details **File Location**: `scripts/tts-xiaoye.sh`, lines 173-186 **Vulnerability Type**: Missing response validation and false success reporting **Risk Level**: Low ### Vulnerable Code ```bash if [[ -n "$CAPTION" ]]; then RESPONSE=$(curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendVoice" \ -F "chat_id=${TARGET}" \ -F "voice=@${AUDIO_FILE}" \ -F "caption=${CAPTION}") else RESPONSE=$(curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendVoice" \ -F "chat_id=${TARGET}" \ -F "voice=@${AUDIO_FILE}") fi printf '{"ok":true,"mode":"send-voice","target":"%s","audio_file":"%s","voice":"%s","caption":"%s"}\n' \ "$TARGET" "$AUDIO_FILE" "$VOICE" "$CAPTION" ``` ### Technical Analysis The Telegram response is captured in `RESPONSE` but never parsed or validated. The script unconditionally emits `"ok":true` after `curl` returns. Telegram commonly represents API-level failures as JSON responses with `"ok":false`; without response validation, invalid credentials, rejected media, inaccessible targets, rate limits, and similar errors can be presented to downstream automation as successful delivery. The invocation also omits explicit HTTP failure handling. Although `set -e` may stop the script for some nonzero `curl` exits, `curl` without `--fail` can return zero after receiving an HTTP error response. More importantly, a valid HTTP response containing Telegram's `"ok":false` still reaches the unconditional success output. ### Attack Path 1. An attacker or operational failure causes the Telegram request to be rejected, such as by supplying an invalid target, revoking the token, blocking access to a chat, or triggering a Telegram API error. 2. Telegram returns an error response, potentially with a successful transport-level `curl` exit status. 3. The script stores but ignores the response. 4. The script prints an object containing `"ok":true`. 5. An agent or ...[truncated 508 chars]
Remediation
## Remediation Suggestions - Invoke `curl` with robust transport and HTTP handling, including `--fail-with-body`, suitable connection timeouts, and a maximum request duration. - Parse `RESPONSE` as JSON and require Telegram's top-level `ok` field to equal `true`. - Return a nonzero exit status when transport, HTTP, parsing, or Telegram API validation fails. - Include Telegram's sanitized error description in standard error without exposing credentials. - Emit the final `"ok":true` result only after confirmed API success. - Add tests covering invalid tokens, invalid chat IDs, rate limiting, malformed responses, and network failures.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The skill description claims specific behaviors and integrations, but the analyzed content does not clearly implement them while also introducing undeclared behaviors like reading local .env credentials and querying the API for voices. Description/behavior mismatches are dangerous because they mislead users and reviewers about what data is accessed and where it is sent, undermining informed consent and safe deployment.

Credential Access

High
Category
Privilege Escalation
Content
AUDIO_DIR="$WORKSPACE/generated/tts-audio"
FFMPEG="$(command -v ffmpeg 2>/dev/null || echo "")"

# Load env vars from .env file (if exists) — required: MINIMAX_API_KEY; optional: TELEGRAM_BOT_TOKEN, TELEGRAM_TARGET
ENV_FILE="$SKILL_DIR/.env"
if [[ -f "$ENV_FILE" ]]; then
  while IFS='=' read -r key value; do
Confidence
78% confidence
Finding
The script automatically reads secrets from a .env file located under a workspace path that may be user-controlled, then exports them into the process environment. This broad, implicit trust of a local file can cause credential misuse or environment poisoning if an attacker can modify the workspace or replace the skill directory contents.

Credential Access

High
Category
Privilege Escalation
Content
FFMPEG="$(command -v ffmpeg 2>/dev/null || echo "")"

# Load env vars from .env file (if exists) — required: MINIMAX_API_KEY; optional: TELEGRAM_BOT_TOKEN, TELEGRAM_TARGET
ENV_FILE="$SKILL_DIR/.env"
if [[ -f "$ENV_FILE" ]]; then
  while IFS='=' read -r key value; do
    [[ -z "$key" || "$key" == \#* ]] && continue
Confidence
78% confidence
Finding
By sourcing credential material from a predictable .env path inside the workspace, the script creates a trust boundary issue: anyone able to alter that file can redirect messaging, substitute API keys, or inject unexpected environment values that influence downstream tools. In an agent-skill context where workspace contents may be synchronized, generated, or user-modifiable, this is more dangerous than in a tightly managed local script.

Credential Access

High
Category
Privilege Escalation
Content
WORKSPACE_DIR = os.path.expanduser("~/.openclaw/workspace")
SKILL_DIR = os.path.join(WORKSPACE_DIR, "skills", "minimax-tts-cn")
DEFAULT_OUTPUT_DIR = os.path.join(WORKSPACE_DIR, "generated", "tmp")
ENV_FILE = os.path.join(SKILL_DIR, ".env")

def load_env_file(path):
    """Load KEY=VALUE pairs from .env file (simple format only)."""
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
# MiniMax TTS Plus - Environment Variables
# Copy this file to .env and fill in your values.
# NEVER commit .env to version control.

# === Required: MiniMax API (https://api.minimaxi.com) ===
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
# MiniMax TTS Plus - Environment Variables
# Copy this file to .env and fill in your values.
# NEVER commit .env to version control.

# === Required: MiniMax API (https://api.minimaxi.com) ===
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
# MiniMax TTS Plus - Environment Variables
# Copy this file to .env and fill in your values.
# NEVER commit .env to version control.

# === Required: MiniMax API (https://api.minimaxi.com) ===
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
# MiniMax TTS Plus - Environment Variables
# Copy this file to .env and fill in your values.
# NEVER commit .env to version control.

# === Required: MiniMax API (https://api.minimaxi.com) ===
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
# MiniMax TTS Plus - Environment Variables
# Copy this file to .env and fill in your values.
# NEVER commit .env to version control.

# === Required: MiniMax API (https://api.minimaxi.com) ===
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
# MiniMax TTS Plus - Environment Variables
# Copy this file to .env and fill in your values.
# NEVER commit .env to version control.

# === Required: MiniMax API (https://api.minimaxi.com) ===
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
# MiniMax TTS Plus - Environment Variables
# Copy this file to .env and fill in your values.
# NEVER commit .env to version control.

# === Required: MiniMax API (https://api.minimaxi.com) ===
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises and documents behaviors that require network, shell, environment-variable, and file access, but it does not declare any explicit tool scope or permissions boundary. This creates a governance and review gap: operators cannot easily constrain what the skill is allowed to do, and the skill may gain broader runtime capabilities than users expect.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
SQP-3 applies to all file types and covers language or locale policy violations. The activation text requires the user to say specific Chinese phrases ("文字模式" or "关闭语音") to stop voice generation, but the document does not offer alternatives or explain that the skill is intentionally limited to Chinese-speaking users.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs users to send generated audio through Telegram and Feishu and to use a third-party TTS API, but it does not clearly warn that user-provided text and derived audio will leave the local environment and be transmitted to external services. This creates a privacy and compliance risk, especially if users pass sensitive, regulated, or confidential content to the skill.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code loads MINIMAX_API_KEY and optional Telegram bot credentials from a .env file and exports them for use, but the only notice is an internal comment. There is no user-facing prompt, warning, or runtime disclosure that the script accesses sensitive credentials.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The script uploads the generated voice file and chat target to Telegram via curl, which is a network transmission of user-provided content and metadata. Although comments describe the channel behavior, there is no explicit user-facing warning in usage output or at send time that data will be transmitted to Telegram.

External Transmission

Medium
Category
Data Exfiltration
Content
# sendVoice: plain voice bubble; with caption = voice + text display
if [[ -n "$CAPTION" ]]; then
  RESPONSE=$(curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendVoice" \
    -F "chat_id=${TARGET}" \
    -F "voice=@${AUDIO_FILE}" \
    -F "caption=${CAPTION}")
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# sendVoice: plain voice bubble; with caption = voice + text display
if [[ -n "$CAPTION" ]]; then
  RESPONSE=$(curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendVoice" \
    -F "chat_id=${TARGET}" \
    -F "voice=@${AUDIO_FILE}" \
    -F "caption=${CAPTION}")
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The code sets `DEFAULT_VOICE` to `Chinese (Mandarin)_Warm_Girl`, which imposes a specific language/locale as the default behavior. There is no accompanying opt-in or user choice mechanism before applying this locale-specific output, so the skill effectively forces Mandarin unless the user knows to override it.

External Transmission

Medium
Category
Data Exfiltration
Content
data = {"voice_type": "all"}

    try:
        resp = requests.post(url, headers=headers, json=data, timeout=30)
        resp.raise_for_status()
        result = resp.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
try:
        print(f"Generating speech...", file=sys.stderr)
        resp = requests.post(url, headers=headers, json=data, timeout=120)
        resp.raise_for_status()
        result = resp.json()
Confidence
88% confidence
Finding
The function transmits the provided text to a third-party API for synthesis, which can expose sensitive user content if callers pass secrets, personal data, or internal information. In the skill context, external transmission is inherent to cloud TTS, so the danger comes from insufficient disclosure/consent and lack of data minimization rather than overtly malicious behavior.

Vague Triggers

Low
Confidence
87% confidence
Finding
This plain-text file provides environment setup information but does not define any explicit activation constraints, trigger phrases, or exclusion conditions for when the related skill should be invoked. For plain-text and manifest-style skill files, missing specificity about invocation scope can lead to unintended activation in broader contexts.

Static analysis

No suspicious patterns detected.