T09 · Insecure Skill Coding Practices
- Location
scripts/ai_hive_mcp.py:15- Finding
Credentials Can Be Sent to a User-Controlled MCP Endpoint
- Content
View full analysis
dict[str, str]: key = os.environ.get("AI_HIVE_API_KEY", "").strip() token = os.environ.get("AI_HIVE_ACCESS_TOKEN", "").strip() if token: return {"authorization": f"Bearer {token}"} if key: return {"x-ai-hive-api-key": key} raise SystemExit( "缺少凭据。OAuth 用户请在 MCP 客户端中完成登录;本脚本调用工具时需通过环境变量提供 " "AI_HIVE_API_KEY,或仅运行 doctor。" ) def post(payload: dict, session_id: str | None = None) -> tuple[dict, str | None]: headers = { "content-type": "application/json", "accept": "application/json, text/event-stream", **auth_headers(), } if session_id: headers["mcp-session-id"] = session_id request = urllib.request.Request( MCP_URL, data=json.dumps(payload, ensure_ascii=False).encode("utf-8"), headers=headers, method="POST", ) ``` ### Technical Analysis The MCP destination is read from the mutable `AI_HIVE_MCP_URL` environment variable. However, `post()` unconditionally adds either the `AI_HIVE_ACCESS_TOKEN` bearer token or the `AI_HIVE_API_KEY` header to requests sent to that destination. The implementation does not verify that the configured URL: - Uses HTTPS. - Resolves to the intended `ai-hive.iclip.cn` host. - Uses the expected `/api/mcp` path. - Belongs to an explicit trusted-origin allowlist. Consequently, control over the process environment or launch configuration is sufficient to redirect authenticated requests to an unrelated server. Endpoint configurability can be useful for testing, but forwarding production credentials to an arbitrary override exceeds the minimum privilege necessary for the ...[truncated 1716 chars]- Remediation
View remediation
str: candidate = os.environ.get("AI_HIVE_MCP_URL", TRUSTED_MCP_URL) parsed = urlsplit(candidate) if ( parsed.scheme != "https" or parsed.hostname != "ai-hive.iclip.cn" or parsed.port not in (None, 443) or parsed.path != "/api/mcp" or parsed.username is not None or pa ...[truncated 179 chars]
