T09 · Insecure Skill Coding Practices
Warning
- Location
- src/translation_dubbing_skill/entry/manifest.py:443
- Finding
- Provider endpoints permit plaintext transmission of API credentials and subtitle content<![CDATA[ ## Vulnerability Details **File Locations**: - `src/translation_dubbing_skill/entry/manifest.py:443-452` - `src/translation_dubbing_skill/entry/manifest.py:511-520` - `src/translation_dubbing_skill/providers/translation/llm.py:224-234` - `src/translation_dubbing_skill/providers/tts/minimax.py:201-208` **Vulnerability Type**: Plaintext transmission of sensitive information through unrestricted provider endpoints **Risk Level**: Medium ### Vulnerable Code The manifest validates provider endpoints only as non-empty strings: ```python translation_endpoint = _require_str( params.get("translation_endpoint"), "translation_endpoint", missing=missing, ) translation_credential = _require_str( params.get("translation_credential"), "translation_credential", missing=missing, ) ``` The same issue applies to TTS endpoints: ```python tts_endpoint = _require_str( params.get("tts_endpoint"), "tts_endpoint", missing=missing_tts ) tts_credential = _require_str( params.get("tts_credential"), "tts_credential", missing=missing_tts ) ``` The translation provider sends the credential and subtitle content to the accepted endpoint: ```python payload = self._build_request_body(entries, target_language, source_language) headers = { "Authorization": f"Bearer {self.credential}", "Content-Type": "application/json", } client = self._get_client() try: response = await client.post( self.endpoint, json=payload, headers=headers ) ``` The MiniMax TTS provider similarly sends its credential and synthesized text payload to the configured endpoint: ```python headers = { "Authorization": f"Bearer {self.credential}", "Content-Type": "application/json", } client = self._get_client() try: response = await client.post( self.endpoint, json=payload, headers=headers ) ``` ### Technical Analysis The endpoint validation logic requires only a non-empty string and does not parse the URL or enforce an encrypted t ...[truncated 3052 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse every provider endpoint with `urllib.parse.urlparse` before constructing provider configuration. 2. Require the `https` scheme for all non-local provider endpoints. 3. If plaintext HTTP is needed for development, require an explicit opt-in and limit it to loopback hosts such as `127.0.0.1`, `::1`, or `localhost`. 4. Reject malformed URLs, URLs without a hostname, unsupported schemes, and URLs containing embedded user information. 5. Apply the validation consistently to translation, generic TTS, LLM TTS, web TTS, and MiniMax endpoints. 6. Consider an optional allowlist of approved provider hosts for managed deployments. 7. Ensure provider requests cannot silently downgrade from HTTPS to HTTP. 8. Document clearly that subtitle text is disclosed to the configured third-party providers. 9. Add automated tests confirming that: - HTTPS endpoints are accepted. - Remote HTTP endpoints are rejected. - Loopback HTTP endpoints require an explicit development option. - Schemes such as `file`, `ftp`, and arbitrary custom schemes are rejected. - Credentials never appear in serialized errors or progress events. ]]>
