T09 · Insecure Skill Coding Practices
- Location
scripts/__main__.py:23- Finding
Unrestricted API Endpoint Allows Credential and Prompt Exfiltration
- Content
View full analysis
Vulnerability Details
File Location:
scripts/__main__.py:23, 34-38, 70-104, 191-209, 262, 291
Vulnerability Type: Unvalidated destination for sensitive authenticated requests
Risk Level: HighThe Skill allows its API destination to be controlled through the
ALIYUN_BAILIAN_API_HOSTenvironment variable, the CLI--base-urloption, or the public Pythonbase_urlparameter. It then sends the Aliyun API key and complete user-supplied prompt or translation text to that destination without validating its scheme or hostname.Vulnerable Code
python DEFAULT_BASE_URL = os.environ.get("ALIYUN_BAILIAN_API_HOST", "https://coding.dashscope.aliyuncs.com/apps/anthropic")python def _get_credentials(api_key: Optional[str] = None, base_url: str = DEFAULT_BASE_URL): key = api_key or os.environ.get("ALIYUN_BAILIAN_API_KEY") if not key: return None, None return key, base_urlThe chat path places the credential in two headers and sends all chat and system-message content to the selected host:
python headers = { "Content-Type": "application/json", "Authorization": f"Bearer {key}", "x-api-key": key, "anthropic-version": "2023-06-01" } # Convert messages to Anthropic format anthropic_messages = [] system_content = None for msg in messages: if msg.get("role") == "system": system_content = msg.get("content", "") else: anthropic_messages.append({ "role": msg.get("role"), "content": msg.get("content", "") }) payload = { "model": model, "messages": anthropic_messages, "temperature": temperature, "max_tokens": max_tokens } if system_content: payload["system"] = system_content if stream: payload["stream"] = True api_url = f"{url}/v1/messages" try: if stream: response = requests.post(api_url, headers=headers, json=payload, ...[truncated 3442 chars]- Remediation
View remediation
Remediation Suggestions
- Parse the destination with a standard URL parser and require the
httpsscheme. - Restrict destinations to an explicit allowlist of supported Alibaba Cloud hosts, such as the documented DashScope regional domains.
- Compare normalized hostnames exactly or by a carefully implemented subdomain rule; do not use substring or suffix checks that accept domains such as
dashscope.aliyuncs.com.attacker.example. - Reject embedded credentials, fragments, unexpected ports, malformed URLs, and IP-literal destinations unless explicitly required.
- Disable redirects for authenticated requests or validate every redirect destination before forwarding authentication headers.
- Remove unrestricted
--base-urland publicbase_urloverrides from normal operation. If custom endpoints are operationally necessary, require an explicit unsafe-development mode and never attach production credentials automatically. - Send only the authentication header required by the official API rather than duplicating the credential in both
Authorizationandx-api-key. - Document that prompts and translation text leave the local environment and identify the approved external provider destinations.
- Add tests confirming that HTTP URLs, arbitrary domains, deceptive domain suffixes, embedded user information, unexpected ports, and cross-domain redirects are rejected before request headers are constructed or transmitted.
- Parse the destination with a standard URL parser and require the
