T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/run.py:102
- Finding
- Unrestricted API Endpoint Can Exfiltrate Credentials and Sensitive Medical Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run.py`, lines 102–111, 226, and 279–287 **Vulnerability Type**: Unrestricted credentialed outbound request **Risk Level**: High ### Vulnerable Code ```python 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) ``` The destination is supplied through an unrestricted command-line option: ```python p.add_argument("--api-url", default=DEFAULT_API_URL, help="OpenAI compatible endpoint URL") ``` The caller-controlled value is then passed directly to the request function: ```python out["answer"] = call_llm( api_url=args.api_url, model=args.model, appkey=args.appkey, system_prompt=system_prompt_for(task_key, args.system_prompt), user_prompt=user_prompt, temperature=float(args.temperature), timeout=int(args.timeout), ) ``` ### Technical Analysis The `--api-url` argument accepts an arbitrary URL without validating its scheme, hostname, port, or trust relationship. `call_llm()` sends an `Authorization: Bearer` header containing the supplied application key and a JSON request body containing the complete medical question to that destination. The implementation does not require HTTPS and does not restrict requests to the documented service domain. Consequently, anyone who can influence the command-line configuration can redirect credentialed requests to an attacker-controlled server. If an HTTP URL is used, credentials and medical content may also be exposed to an on-path network attacker. This is particularly sensitive because the skill is designed to process medical records and reports. The project documentation recommends de-identification, but this operational recommendation does not enforce a technical security boundary. ### Attack Path 1. An attacker gains influence over the skil ...[truncated 1477 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Restrict destinations by default** - Permit only the documented API hostname or an explicit allowlist of approved service domains. - Compare parsed, normalized hostnames rather than using substring or suffix checks that can be bypassed. 2. **Require encrypted transport** - Reject every URL whose parsed scheme is not `https`. - Do not provide an option to silently downgrade to plaintext HTTP in production. 3. **Control redirects** - Reject redirects to a different origin. - Do not forward the `Authorization` header across scheme, hostname, or port changes. - Consider disabling redirects entirely for authenticated API calls. 4. **Separate custom endpoints from production credentials** - If custom endpoints are operationally required, require a conspicuous unsafe opt-in. - Require separate credentials scoped specifically to each approved endpoint. - Never attach the production service key to an untrusted custom host. 5. **Apply least privilege to API keys** - Use narrowly scoped, short-lived credentials where supported. - Enforce usage quotas and monitor for anomalous source addresses or request volumes. - Provide a rapid credential-revocation and rotation process. 6. **Reduce sensitive-data exposure** - Enforce or automate de-identification before transmission. - Clearly identify the external data-processing boundary to operators. - Avoid logging authorization headers or complete medical request bodies. 7. **Validate the URL before creating the request** - Parse the URL with a standard URL parser. - Verify the exact scheme, normalized hostname, permitted port, and expected path. - Resolve and reject loopback, link-local, private, and metadata-service addresses unless explicitly required by a trusted deployment design. ]]>
