T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/run.py:183
- Finding
- Arbitrary LLM Endpoint Can Expose API Credentials and Sensitive Medical Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run.py:183-194, 211-222` **Vulnerability Type**: Unrestricted transmission of credentials and sensitive data to a user-controlled endpoint **Risk Level**: High ### Vulnerable Code ```python def call_llm(prompt: str, *, base: str, model: str, appkey: str, timeout: int) -> str: url = f"{base.rstrip('/')}/chat/completions" headers = {"Authorization": f"Bearer {appkey}"} if appkey else {} payload = { "model": model, "messages": [{"role": "user", "content": prompt}], "temperature": 0, } response = _http_post(url, payload, headers, timeout=timeout) try: return str(response["choices"][0]["message"]["content"]).strip() except (KeyError, IndexError, TypeError) as exc: raise RuntimeError(f"Unexpected LLM response: {response}") from exc ``` ```python parser.add_argument( "--base", default=DEFAULT_LLM_BASE, help=f"内部大模型 base URL(默认:{DEFAULT_LLM_BASE})。", ) parser.add_argument("--model", default=DEFAULT_LLM_MODEL, help=f"模型名称(默认:{DEFAULT_LLM_MODEL})。") parser.add_argument("--timeout", type=int, default=0, help="HTTP 超时秒数;0 表示一直等待(默认:0)。") parser.add_argument("--appkey", required=True, help="必须传入。内部医疗大模型鉴权 key,使用 Bearer 方式认证。") ``` ### Technical Analysis The `--base` argument accepts an arbitrary URL and is used directly to construct the LLM request destination. The code performs no validation of the URL scheme, destination hostname, port, or origin before attaching the Bearer credential and sending the complete generated prompt. The prompt can contain sensitive medical-record content. Consequently, anyone able to control the command-line arguments or the workflow configuration can redirect both the medical data and the API credential to an attacker-controlled server. The unrestricted URL may also permit requests to network services reachable from the execution environment. The vulnerability is especially significant because the ...[truncated 1620 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the `--base` override from production deployments when only one approved service is required. 2. If configurability is necessary, enforce an explicit allowlist of approved HTTPS hostnames and ports. 3. Parse the URL with `urllib.parse.urlsplit` and reject: - Non-HTTPS schemes. - Embedded usernames or passwords. - Unapproved hostnames and ports. - IP literals and loopback, link-local, private, or reserved addresses unless explicitly required. 4. Bind the Authorization header to the approved origin. Never forward it when the destination origin differs. 5. Disable automatic cross-origin redirects or revalidate every redirect target before following it. 6. Store the API credential in a protected secret manager or environment-based secret channel rather than exposing it in process arguments. 7. Apply outbound firewall or proxy controls so the process can reach only the approved LLM service. 8. Minimize and de-identify medical content before transmission, and establish explicit remote retention and deletion controls. 9. Add tests confirming that malicious, plaintext, local, and unapproved endpoint URLs are rejected. ]]>
