T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/run.py:65
- Finding
- Arbitrary API Endpoint Allows Bearer Credential and Medical Data Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run.py:65-83` (credential transmission sink); `scripts/run.py:213` (user-controlled endpoint source) **Vulnerability Type**: Unrestricted sensitive-data destination / credential disclosure **Risk Level**: High ### Vulnerable Code The API endpoint is accepted directly from a command-line argument without validation: ```python p.add_argument("--api-url", default=DEFAULT_API_URL, help="OpenAI 兼容接口地址") ``` The supplied endpoint then receives the bearer credential and medical question: ```python payload = { "model": model, "temperature": temperature, "messages": [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ], } try: req = Request( api_url, data=json.dumps(payload, ensure_ascii=False).encode("utf-8"), headers={ "Content-Type": "application/json", "Authorization": f"Bearer {appkey}", }, ) resp = urlopen(req, timeout=timeout) body = json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis The `--api-url` argument is unrestricted and flows into `urllib.request.Request` as the request destination. The request always includes the caller-provided API key in an `Authorization: Bearer` header and includes the complete question in its JSON body. No validation enforces HTTPS, checks the destination hostname against an allowlist, prevents requests to local or private-network addresses, or requires separate credentials when a custom provider is selected. Consequently, any party capable of influencing the script's invocation arguments can redirect sensitive information to an endpoint under its control. A plaintext `http://` endpoint can also expose the credential and medical content to network observers. This is not merely generic configurable networking: the same production credential intended for the documented service is automatically forwarded to t ...[truncated 1854 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Prefer a fixed endpoint** - Remove `--api-url` if alternate providers are not a genuine operational requirement. - Send the production key only to the documented HTTPS service. 2. **Enforce an explicit destination allowlist** - Parse the URL with `urllib.parse.urlsplit`. - Require the `https` scheme. - Reject embedded credentials, fragments, unexpected ports, and malformed hostnames. - Compare the normalized hostname against an exact allowlist such as `maas-api.hivoice.cn`; do not rely on substring or suffix checks. 3. **Separate credentials by provider** - Never forward the key for the default service to custom endpoints. - If custom providers must be supported, require a separately named credential explicitly associated with the selected provider. 4. **Restrict redirects** - Disable redirects or validate every redirect target before following it. - Ensure authorization headers are never sent to a different origin. 5. **Prevent internal-network targeting** - Resolve the hostname and reject loopback, link-local, private, multicast, reserved, and metadata-service addresses. - Revalidate resolved addresses when connecting to reduce DNS rebinding risk. - Apply outbound network controls so the process can reach only approved API hosts. 6. **Protect secret handling** - Read the API key from a protected environment variable, secret manager, or descriptor-based input rather than a command-line argument, because command-line values may be visible in process listings or execution logs. - Redact authorization data from logs and error reporting. - Rotate any credential that may already have been sent to an untrusted endpoint. 7. **Add security tests** - Verify rejection of `http://` URLs, unapproved domains, deceptive hostnames, localhost, private IP addresses, and cross-origin redirects. - Verify that the approved endpoint remains functional and receives credentials only ove ...[truncated 20 chars]
