T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/tts.py:151
- Finding
- Unrestricted API Endpoint Override Can Disclose API Credentials and Voice Samples<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/tts.py:16, 57-64, 118-126, 151-176` - `scripts/mimo_tts.py:28, 50-59, 88-90` - `scripts/mimo_tts_voicedesign.py:17, 38-43, 76-78` - `scripts/mimo_tts_voiceclone.py:18, 47-76, 88-110` **Vulnerability Type**: Unvalidated destination for sensitive network requests **Risk Level**: Medium **Classification**: T09: Insecure Skill Coding Practices ### Relevant Code The unified entry point accepts an endpoint from the environment: ```python API_BASE = os.getenv("MIMO_API_BASE", "https://token-plan-cn.xiaomimimo.com/v1") ``` It sends the API key and synthesis payload to that endpoint without validating the scheme or destination host: ```python def _call_api(payload: dict, api_key: str, max_retries: int = 3) -> bytes: data = json.dumps(payload).encode() req = urllib.request.Request( f"{API_BASE}/chat/completions", data=data, headers={"Content-Type": "application/json", "api-key": api_key}, method="POST", ) ``` Clone mode reads and Base64-encodes the user-selected voice sample: ```python def _read_clone_audio(path: str) -> Tuple[str, str]: if not os.path.exists(path): raise TtsError(f"音频文件不存在: {path}") suffix = os.path.splitext(path)[1].lower() mime_map = {".mp3": "audio/mpeg", ".wav": "audio/wav"} mime = mime_map.get(suffix) if not mime: raise TtsError(f"不支持的音频格式: {suffix},仅支持 mp3/wav") with open(path, "rb") as f: voice_bytes = f.read() if len(voice_bytes) > 10 * 1024 * 1024: raise TtsError("音频文件过大(最大 10 MB)") voice_b64 = base64.b64encode(voice_bytes).decode("utf-8") return f"data:{mime};base64,{voice_b64}", mime ``` The command-line interface also permits an unrestricted endpoint override: ```python parser.add_argument("--base-url", default=None, help="自定义 API 端点 URL(覆盖 MIMO_API_BASE 环境变量)") args = parser.parse_args() if args.base_url: global API_BASE API_B ...[truncated 4675 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Allowlist official endpoints by default** - Permit only documented MiMo origins such as: - `https://api.xiaomimimo.com/v1` - `https://token-plan-cn.xiaomimimo.com/v1` - Compare normalized hostnames rather than using substring matching. 2. **Require HTTPS** - Reject `http://`, `file://`, and all non-HTTPS schemes. - Reject URLs containing embedded usernames or passwords. - Reject unexpected ports unless explicitly approved. 3. **Make custom endpoints an explicit high-risk mode** - Remove unrestricted `--base-url` behavior from normal operation, or require a separate flag such as `--allow-untrusted-endpoint`. - Display the normalized destination before transmitting credentials. - Require confirmation before uploading a voice sample to a non-official host. 4. **Separate credentials by destination** - Do not send `MIMO_API_KEY` to an unapproved custom endpoint. - Require a separate endpoint-specific credential for compatible third-party services. 5. **Validate redirects** - Prevent authorization headers and sensitive request bodies from being forwarded to a different origin. - Reject cross-origin redirects. - Verify the final response origin before accepting returned data. 6. **Add privacy warnings for clone mode** - Clearly state that the complete selected recording will be uploaded. - Show the destination host before reading and transmitting the file. - Recommend samples that contain no unrelated conversations or sensitive background audio. 7. **Apply centralized validation** - Implement one URL-validation function and use it in all four scripts so the OpenAI and `urllib` paths enforce identical restrictions. ]]>
