T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/eval.py:874
- Finding
- API Credential Disclosure Through Provider and Endpoint Mismatch## Vulnerability Details **File Location**: `scripts/eval.py`, lines 874-896 **Vulnerability Type**: API credential disclosure and insufficient endpoint validation **Risk Level**: High ### Vulnerable Code ```python def llm_judge(result: dict) -> dict | None: api_key = os.environ.get('OPENAI_API_KEY') or os.environ.get('DEEPSEEK_API_KEY', '') if not api_key: return None base = os.environ.get('OPENAI_API_BASE', 'https://api.deepseek.com') dim_lines = '\n'.join(f' {k}: {v}' for k, v in {**result['dimension_scores'], **result['expanded_scores']}.items()) ev_lines = '\n'.join(f' {e["metric"]}: {e["value"]}' for e in result['evidence'][:8]) risk_lines = '\n'.join(f' - {r}' for r in result['risk_flags']) or ' 无' prompt = LLM_JUDGE_PROMPT.format( dim_summary=dim_lines, evidence_summary=ev_lines, risk_summary=risk_lines) payload = json.dumps({ 'model': 'deepseek-chat', 'messages': [{'role': 'user', 'content': prompt}], 'temperature': 0.3, 'max_tokens': 200, }).encode() req = urllib.request.Request( f'{base}/v1/chat/completions', data=payload, headers={'Content-Type': 'application/json', 'Authorization': f'Bearer {api_key}'}, ) try: with urllib.request.urlopen(req, timeout=15) as resp: body = json.loads(resp.read()) ``` ### Technical Analysis Credential selection and endpoint selection are not bound to the same provider. The code prefers `OPENAI_API_KEY`, but the default endpoint is `https://api.deepseek.com`. Consequently, when an OpenAI key is present and `OPENAI_API_BASE` is absent, that OpenAI credential is transmitted to DeepSeek in the HTTP `Authorization` header. In addition, `OPENAI_API_BASE` is accepted without host validation. Any process or execution environment able to influence this variable can redirect the request to an arbitrar ...[truncated 1610 chars]
- Remediation
- ## Remediation Suggestions 1. Require explicit provider selection, such as `--provider openai` or `--provider deepseek`. 2. Bind each provider to its corresponding key and default endpoint: - OpenAI: `OPENAI_API_KEY` and the official OpenAI API endpoint. - DeepSeek: `DEEPSEEK_API_KEY` and the official DeepSeek API endpoint. 3. Do not fall back from one provider's credential to another provider's endpoint. 4. Validate the parsed URL before constructing the request: - Require HTTPS. - Require an approved hostname. - Reject embedded credentials, unexpected ports, fragments, and non-HTTP schemes. 5. If custom endpoints are necessary, require a dedicated opt-in flag and a provider-specific base variable. 6. Display the destination hostname and categories of data being transmitted before the optional request. 7. Minimize transmitted evidence and redact values that may contain workspace-specific or operationally sensitive information. 8. Add automated tests proving that an OpenAI key cannot be sent to DeepSeek and that unapproved hosts are rejected.
