Back to skill

Security audit

MiniMax Speech 2.8

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its MiniMax text-to-speech purpose, but it needs review because it can send the user’s MiniMax API key and text to arbitrary endpoints and fetch arbitrary returned URLs.

Install only if you are comfortable with the skill using a MiniMax API key and sending requested text to MiniMax. Avoid custom --endpoint values unless you fully trust the destination, avoid --output-format url in sensitive environments, and use a least-privileged or disposable MiniMax key where possible.

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

Error
Location
scripts/minimax_tts.py:104
Finding

MiniMax API Credential Disclosure Through Unrestricted Endpoint Overrides

Content
View full analysis
None: api_key = ensure_api_key() headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } ``` ```python response = requests.post( args.endpoint, headers=headers, json=payload, timeout=args.timeout, ) ``` ```python def run_voices(args: argparse.Namespace) -> None: api_key = ensure_api_key() headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } payload = {"voice_type": args.voice_type} try: response = requests.post( args.endpoint, headers=headers, json=payload, timeout=args.timeout, ) ``` ```python tts_parser.add_argument( "--endpoint", default="https://api.minimax.io/v1/t2a_v2", help="Override MiniMax T2A endpoint", ) ``` ```python voices_parser.add_argument( "--endpoint", default="https://api.minimax.io/v1/get_voice", help="Override the catalog endpoint", ) ``` ### Technical Analysis Both CLI subcommands accept an unrestricted `--endpoint` argument. The script then attaches the value of `MINIMAX_API_KEY` as an HTTP bearer token to a request sent to that destination. Sending the credential to the default official MiniMax endpoints is necessary for the declared functionality. Allowing any caller-controlled host to receive the same credential is not necessary and violates least-privilege network handling. The code does not enforce HTTPS, validate the hostname, constrain the URL path, or require confirmation before sending the credential to a non-default destination. Consequently, an untrusted command, copied usage instruction, or ac ...[truncated 1369 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/minimax_tts.py:29
Finding

Server-Controlled Audio URL Enables Server-Side Request Forgery

Content
View full analysis
bytes: if output_format == "hex": return bytes.fromhex(audio_payload) if output_format == "base64": return base64.b64decode(audio_payload) if output_format == "url": resp = requests.get(audio_payload, timeout=60) resp.raise_for_status() return resp.content fail(f"Unsupported output format: {output_format}") ``` ```python audio_payload = data.get("data", {}).get("audio") if not audio_payload: fail(f"No audio payload returned: {json.dumps(data)}") audio_bytes = decode_audio(audio_payload, args.output_format) out_file = Path(args.output or f"minimax_tts_output.{args.audio_format}") ``` ### Technical Analysis When `--output-format url` is selected, the script treats the API response's `data.audio` field as a trusted URL and performs a GET request without validating its scheme, hostname, resolved address, redirect chain, content type, or response size. A compromised API service or a custom endpoint can return a URL targeting localhost, private network ranges, link-local services, or cloud metadata endpoints. Because `requests.get()` follows redirects by default, an initially acceptable URL could also redirect to an internal destination. The use of `resp.content` buffers the complete response in memory. There is no maximum download size, so a malicious or unexpectedly large response can cause excessive memory consumption and subsequently consume disk space when written to the output file. The flagged decode-and-execute pattern is not present: hex and base64 data are decoded into bytes and written as audio, but the script does not execute those bytes. The security issue is the unrestricted network retrieval, no ...[truncated 1825 chars]
Remediation
View remediation
MAX_AUDIO_BYTES: fail("Audio response exceeds the permitted size") chunks.append(chunk) return b"".join(chunks) ``` 6. Verify that the response `Content-Type` is an expected audio media type and reject HTML, JSON, and arbitrary binary responses. 7. Prefer returning hex or base64 audio through the already authenticated API response if URL-based retrieval is not required. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

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

Critical
Category
Data Flow
Confidence
98% confidence
Finding

The script sends an Authorization bearer token sourced from MINIMAX_API_KEY to a user-controlled --endpoint. Because the endpoint is overrideable without validation, an operator can unintentionally exfiltrate the API key and request contents to any remote host, turning a MiniMax-specific helper into a generic credentialed HTTP client.

Content

Scanner excerpt · scripts/minimax_tts.py (reported line 131)May include surrounding context.

python
if timbre_weights:
        payload["timbre_weights"] = timbre_weights
    try:
        response = requests.post(args.endpoint, headers=headers, json=payload, timeout=args.timeout)
        response.raise_for_status()
    except requests.RequestException as exc:
        fail(f"TTS request failed: {exc}")

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

Critical
Category
Data Flow
Confidence
98% confidence
Finding

The voice catalog path has the same issue: it transmits the bearer token from the environment to any URL supplied via --endpoint. This can leak the API key to attacker-controlled infrastructure and enables unauthorized reuse of the credential.

Content

Scanner excerpt · scripts/minimax_tts.py (reported line 157)May include surrounding context.

python
}
    payload = {"voice_type": args.voice_type}
    try:
        response = requests.post(args.endpoint, headers=headers, json=payload, timeout=args.timeout)
        response.raise_for_status()
    except requests.RequestException as exc:
        fail(f"Voice catalog request failed: {exc}")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs the agent to use environment variables, write output files, and make outbound network requests, but it does not declare any explicit tool scope or permissions boundary. This creates a governance and least-privilege gap: an orchestrator or reviewer cannot easily constrain or approve sensitive capabilities before the skill is used.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

The skill sends user-provided text and an API credential to an external third-party service, which is a real data egress and secret-use boundary. While expected for a TTS integration, it is still security-relevant because sensitive prompts or regulated content could be transmitted off-system without clear consent and endpoint restrictions.

Content

Scanner excerpt · SKILL.md (reported line 11)May include surrounding context.

md
1. **Install dependencies.** Run `pip install requests` in the environment that will execute the script. The CLI talks to MiniMax's REST API, so you only need the `requests` library on top of Python 3.11+.
2. **Set your MiniMax credential.** Export `MINIMAX_API_KEY` with the API key the user promised to supply. The script will refuse to run without it.
3. **Use the bundled CLI.** `scripts/minimax_tts.py` exposes two subcommands:
   - `tts`: calls `POST https://api.minimax.io/v1/t2a_v2` (Speech 2.8 T2A HTTP) with the desired voice_id, voice settings, audio configuration, and optional voice effects. Example:
     ```bash
     python scripts/minimax_tts.py tts \
       --text "Tonight in Shenzhen the skies are clear." \

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The --endpoint override permits changing the remote destination from the default MiniMax API to another region or potentially any arbitrary URL, increasing the risk of SSRF-like misuse, unintended data exfiltration, or credential exposure to untrusted hosts. This makes the external transmission more dangerous than a fixed, documented API integration.

Content

Scanner excerpt · SKILL.md (reported line 21)May include surrounding context.

md
--output minimax-weather.mp3
     ```
     The script decodes the hex/base64 payload, saves the file, and prints metadata. Override the endpoint with `--endpoint` if you must hit `https://api-uw.minimax.io/v1/t2a_v2` or another region.
   - `voices`: calls `POST https://api.minimax.io/v1/get_voice` to enumerate `system`, `voice_cloning`, `voice_generation`, or `all` categories. Example:
     ```bash
     python scripts/minimax_tts.py voices --voice-type all --print-response
     ```

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

When output_format is url, the script blindly fetches whatever URL the API response contains. If the upstream service is compromised, misconfigured, or if a custom endpoint is used, this creates an SSRF-style primitive that can reach unintended internal or external resources beyond the declared MiniMax API interaction.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/minimax_tts.py (reported line 131)May include surrounding context.

python
if timbre_weights:
        payload["timbre_weights"] = timbre_weights
    try:
        response = requests.post(args.endpoint, headers=headers, json=payload, timeout=args.timeout)
        response.raise_for_status()
    except requests.RequestException as exc:
        fail(f"TTS request failed: {exc}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/minimax_tts.py (reported line 157)May include surrounding context.

python
if timbre_weights:
        payload["timbre_weights"] = timbre_weights
    try:
        response = requests.post(args.endpoint, headers=headers, json=payload, timeout=args.timeout)
        response.raise_for_status()
    except requests.RequestException as exc:
        fail(f"TTS request failed: {exc}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/minimax_tts.py (reported line 210)May include surrounding context.

python
choices=["hex", "url", "base64"],
                             help="How the API returns audio data")
    tts_parser.add_argument("--output", help="Override output file path")
    tts_parser.add_argument("--endpoint", default="https://api.minimax.io/v1/t2a_v2",
                             help="Override MiniMax T2A endpoint")
    tts_parser.add_argument("--timeout", type=int, default=120,
                             help="HTTP timeout in seconds")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/minimax_tts.py (reported line 221)May include surrounding context.

python
choices=["hex", "url", "base64"],
                             help="How the API returns audio data")
    tts_parser.add_argument("--output", help="Override output file path")
    tts_parser.add_argument("--endpoint", default="https://api.minimax.io/v1/t2a_v2",
                             help="Override MiniMax T2A endpoint")
    tts_parser.add_argument("--timeout", type=int, default=120,
                             help="HTTP timeout in seconds")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The TTS CLI exposes --endpoint as a free-form URL override while still attaching the API bearer token and user-provided text. This expands the tool from a scoped MiniMax helper into a generic outbound HTTP client capable of credential and data exfiltration.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The voice catalog command also permits arbitrary endpoint override, allowing authenticated requests to be sent to non-MiniMax destinations. In this skill context, that is more dangerous because the command appears purpose-limited, so users may not expect it can be repurposed for exfiltration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill tells users to save audio and JSON outputs to disk but does not mention overwrite risks, safe output directories, or validation of output paths. In automation contexts, this can lead to accidental overwriting of local files or writing sensitive API responses to unintended locations.

Content

No source excerpt is available for this finding.