T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/evaluate_vibe.py:5
- Finding
- OpenAI API Key May Be Transmitted to the Default DeepSeek Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/evaluate_vibe.py`, lines 5-18 **Vulnerability Type**: Provider credential and endpoint mismatch **Risk Level**: High ### Vulnerable Code ```python API_KEY = os.environ.get("OPENAI_API_KEY") or os.environ.get("DEEPSEEK_API_KEY", "") API_BASE = os.environ.get("OPENAI_API_BASE", "https://api.deepseek.com") MODEL = os.environ.get("LLM_MODEL", "deepseek-chat") def call_llm(prompt): if not API_KEY: return "[错误] 请设置 OPENAI_API_KEY 或 DEEPSEEK_API_KEY" payload = json.dumps({"model": MODEL, "messages": [ {"role": "system", "content": "你是一位资深 AI 编程工具专家,深度使用过 Cursor、Windsurf、Bolt、v0、Replit AI 等工具。你能准确评估哪些任务适合 vibe coding,哪些需要人工介入。请用中文回答,使用 Markdown 格式。"}, {"role": "user", "content": prompt} ], "temperature": 0.7}).encode() req = urllib.request.Request(f"{API_BASE}/chat/completions", data=payload, headers={"Content-Type": "application/json", "Authorization": f"Bearer {API_KEY}"}) with urllib.request.urlopen(req, timeout=60) as r: ``` ### Technical Analysis The credential-selection logic and endpoint-selection logic are not coupled to the same provider. `OPENAI_API_KEY` is selected before `DEEPSEEK_API_KEY`, but the default API endpoint is `https://api.deepseek.com`. Consequently, when `OPENAI_API_KEY` exists and `OPENAI_API_BASE` is absent, the program places the OpenAI credential in an HTTP bearer authorization header and transmits it to DeepSeek. The independently configurable API base can also cause a selected credential to be sent to another unintended endpoint if the environment is incorrectly or maliciously configured. The HTTPS connection protects the credential in transit from passive network interception, but it does not prevent the destination server from receiving and retaining the bearer credential. ### Attack Path 1. An OpenAI API credential is present in the process environment as `OPENAI_API_KEY`. 2. `OPENAI_API_BASE` is unset, so the ap ...[truncated 1236 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Couple each credential explicitly to its provider endpoint: - Use `OPENAI_API_KEY` only with a validated OpenAI endpoint. - Use `DEEPSEEK_API_KEY` only with a validated DeepSeek endpoint. 2. Do not silently prioritize one provider's key while defaulting to another provider's service. 3. Introduce an explicit provider setting, such as `LLM_PROVIDER=openai` or `LLM_PROVIDER=deepseek`, and derive the key, endpoint, and default model from that selection. 4. Reject conflicting configurations, including multiple provider keys without an explicit provider selection. 5. Validate the destination host against an allowlist before attaching an authorization header. Require a separate, explicit opt-in for custom endpoints. 6. Fail closed when the selected key does not match the configured provider or endpoint. 7. Document that the project description and skill-level input are transmitted to an external LLM service. 8. Revoke and rotate any OpenAI credential that may already have been transmitted to the default DeepSeek endpoint. ]]>
