T09 · Insecure Skill Coding Practices
- Location
scripts/minimax_music.py:21- Finding
API credential and user-content disclosure through an unrestricted endpoint
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is largely a disclosed frontend and media-generation helper, but its MiniMax scripts can send API keys and user prompts to an arbitrary environment-configured endpoint and fetch unvalidated media URLs.
Review this before installing if you will use MiniMax media generation. Only set MINIMAX_API_BASE to official MiniMax HTTPS endpoints, keep the API key narrowly scoped and revocable, avoid putting confidential text or lyrics into prompts, and be cautious with returned download URLs and unpinned package installation. The skill does not show evidence of intentional theft or persistence, but its current endpoint and download handling are too broad for a clean benign install.
scripts/minimax_music.py:21API credential and user-content disclosure through an unrestricted endpoint
scripts/minimax_image.py:76Unvalidated response-directed downloads permit SSRF and unbounded file retrieval
references/env-setup.md:8Unpinned third-party package installation creates supply-chain exposure
templates/viewer.html:23Browser template retrieves and executes remote JavaScript without integrity verification
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
if seed is not None:
payload["seed"] = seed
resp = requests.post(
f"{API_BASE}/image_generation",
headers=_headers(),
json=payload,
The request target is taken directly from the MINIMAX_API_BASE environment variable and used to send a Bearer token plus user-supplied prompt/lyrics to whatever host is configured. If an attacker can influence the environment, this becomes an SSRF/exfiltration sink that can leak credentials and content to an attacker-controlled endpoint; the frontend/media-generation context increases sensitivity because prompts and lyrics may contain proprietary or user data.
if lyrics_optimizer:
payload["lyrics_optimizer"] = True
resp = requests.post(
f"{API_BASE}/music_generation",
headers={
"Authorization": f"Bearer {API_KEY}",
The request destination is taken directly from the MINIMAX_API_BASE environment variable and the Authorization bearer token is sent to that endpoint. If an attacker or untrusted runtime controls the environment, they can redirect requests to an arbitrary server and exfiltrate the API key and user-provided text, making this an SSRF-style credential leakage issue rather than a harmless configuration choice.
"output_format": "hex",
}
resp = requests.post(
f"{API_BASE}/t2a_v2",
headers={
"Authorization": f"Bearer {API_KEY}",
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"prompt_optimizer": prompt_optimizer,
}
resp = requests.post(
f"{API_BASE}/video_generation",
headers=_headers(),
json=payload,
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"""Poll task status until Success. Returns file_id."""
elapsed = 0
while elapsed < max_wait:
resp = requests.get(
f"{API_BASE}/query/video_generation",
headers=_headers(),
params={"task_id": task_id},
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
def download_video(file_id: str, output_path: str):
"""Retrieve download URL via file_id and save the video."""
resp = requests.get(
f"{API_BASE}/files/retrieve",
headers=_headers(),
params={"file_id": file_id},
The declared description presents a broad frontend development and creative web production skill focused on premium UI design, motion, copywriting, and media generation in the context of building web pages. The supplied code does not implement frontend development, page generation, animations, copywriting, or visual art workflows. Instead, it is narrowly a synchronous text-to-speech client for the MiniMax API, taking text input, calling an external TTS endpoint with an API key, decoding returned hex audio, and writing audio files locally. While the description mentions generating media assets including audio/music, this code’s primary purpose is specifically TTS generation and file export, which is materially different from the declared primary skill of full-stack frontend/web experience creation.
The declared description presents a comprehensive frontend development and creative-production skill centered on building visually striking web pages and related assets. The supplied code does not implement frontend development or page-building behavior at all. Instead, it is a standalone command-line script for one specific backend task: generating a video from text via the MiniMax API, polling task status, and downloading the resulting file. While the description does mention generating media assets, that reference is much broader and embedded in a web-development skill; the actual code’s primary purpose is materially different and much narrower. It also performs undeclared external API access and local file download/storage using API keys. Therefore the description does not accurately represent the code chunk.
The supplied code does not implement a broad frontend-development or media-generation skill. Instead, it is a narrow JavaScript template for p5.js generative art sketches. It includes seeded randomness, p5 lifecycle scaffolding, utility helpers, parameter updates, and image export, but no page-building logic, no UI framework usage, no copywriting, no AI/media-generation integrations, and no cinematic web animation system. While generative art is one small subset of the declared description, the actual code’s primary purpose is materially narrower and different from the declared all-in-one frontend and creative production capability.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
## 3.2 Workflow
1. **Parse:** type, quantity, style, spec, usage
2. **Craft prompt:** Be specific (composition, lighting, style). **NEVER** include text in image prompts.
3. **Execute:** Show prompt to user, **MUST confirm before generating**, then run script
4. **Save:** `<project>/public/assets/{images,videos,audio}/` as `{type}-{descriptor}-{timestamp}.{ext}` — **MUST save locally**
5. **Post-process:** Images → WebP, Videos → ffmpeg compress, Audio → normalize
6. **Deliver:** File path + code snippet + CSS suggestion
The skill explicitly references environment variables, local file access, and external API-backed generation scripts, but it does not declare any tool scope or allowed-tools restrictions. In an agent environment, this creates unnecessary ambiguity about what capabilities the skill may exercise and increases the chance of overbroad execution, especially where network and filesystem actions are involved.
The instruction "ANTI-EMOJI POLICY: NEVER use emojis anywhere" imposes a communication-style restriction that functions as a language/locale policy without any user choice or documented justification. This can conflict with user preferences or accessibility/communication norms and is stated as a mandatory rule.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
brew install ffmpeg
sudo apt install ffmpeg
## 3. Quick test
Skill contains patterns that could indirectly extract system prompts through rephrasing, translation, summarization, or side-channel techniques.
| 1002 | Rate limit | Wait and retry |
| 1004 | Auth failed | Check API key |
| 1008 | Insufficient balance | Top up account |
| 1026 | Content flagged | Rephrase prompt/lyrics |
| 2013 | Invalid parameters | Check prompt/lyrics length |
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
python scripts/minimax_video.py "City skyline at sunset [Push in]" -o city.mp4 --duration 10 --resolution 1080P
python scripts/minimax_video.py "Exact prompt I want used" -o out.mp4 --no-optimize
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
python scripts/minimax_video.py "City skyline at sunset [Push in]" -o city.mp4 --duration 10 --resolution 1080P
python scripts/minimax_video.py "Exact prompt I want used" -o out.mp4 --no-optimize
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
# 10 seconds, 1080P
python scripts/minimax_video.py "City skyline at sunset [Push in]" -o city.mp4 --duration 10 --resolution 1080P
# Disable prompt auto-optimization
python scripts/minimax_video.py "Exact prompt I want used" -o out.mp4 --no-optimize
```
The document makes gender matching a mandatory, non-negotiable rule for voice selection, which can encode discriminatory behavior into downstream applications. In a frontend/content-generation skill, this guidance may cause systems to deny user preference, mis-handle nonbinary or ambiguous characters, and produce biased UX decisions at scale.
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
ritated male voice | Drama, comedy |
| `Spanish_AssertiveQueen` | Assertive Queen | Confident, commanding queen voice | Drama, fantasy |
| `Spanish_CaringGirlfriend` | Caring Girlfriend | Nurturing, loving girlfriend voice | Romance, relationship |
| `Spanish_PowerfulSoldier` | Powerful Soldier | Strong, brave soldier voice | Action, military |
| `Spanish_PassionateWarrior` | Passionate Warrior | Fierce, dedicated warrior voice | Action, fantasy |
| `Spanish_ChattyGirl` | Chatty Girl | Talkative, sociable girl voice | Comedy, social |
| `Spanish_RomanticHusband` | Romantic Husband | Loving, romantic husband voice | Romance, family |
| `Spanish_CompellingGirl` | CompellingGirl | Persuasive, magnetic girl voice | Marketing, entertainment |
| `Spanish_PowerfulVeteran` | Powerful Veteran | Experienced, strong veteran voice | Military, drama |
| `Spanish_SensibleManager` | Sensible Manager | Practical, reasonable manager voice | Business, guidance |
| `Spanish_ThoughtfulLady` | Thoughtful L
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
brew install ffmpeg
# Ubuntu
sudo apt install ffmpeg
# Verify
ffmpeg -version
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import requests
API_KEY = os.getenv("MINIMAX_API_KEY")
# China Mainland: https://api.minimaxi.com/v1
# Overseas: https://api.minimax.io/v1
API_BASE = os.getenv("MINIMAX_API_BASE")
if not API_BASE:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import requests
API_KEY = os.getenv("MINIMAX_API_KEY")
# China Mainland: https://api.minimaxi.com/v1
# Overseas: https://api.minimax.io/v1
API_BASE = os.getenv("MINIMAX_API_BASE")
if not API_BASE:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import requests
API_KEY = os.getenv("MINIMAX_API_KEY")
# China Mainland: https://api.minimaxi.com/v1
# Overseas: https://api.minimax.io/v1
API_BASE = os.getenv("MINIMAX_API_BASE")
if not API_BASE:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import requests
API_KEY = os.getenv("MINIMAX_API_KEY")
# China Mainland: https://api.minimaxi.com/v1
# Overseas: https://api.minimax.io/v1
API_BASE = os.getenv("MINIMAX_API_BASE")
if not API_BASE:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
API_KEY = os.getenv("MINIMAX_API_KEY")
# China Mainland: https://api.minimaxi.com/v1
# Overseas: https://api.minimax.io/v1
API_BASE = os.getenv("MINIMAX_API_BASE")
if not API_BASE:
raise SystemExit("ERROR: MINIMAX_API_BASE is not set.")