T09 · Insecure Skill Coding Practices
- Location
scripts/ai_hive_mcp.py:15- Finding
Credentials Can Be Exfiltrated Through a User-Overridable 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 script reads `AI_HIVE_API_KEY` or `AI_HIVE_ACCESS_TOKEN` from the environment and attaches the resulting credential to every MCP request. However, the destination is independently controlled by the `AI_HIVE_MCP_URL` environment variable. The code does not validate that the configured URL: - Uses HTTPS. - Has the exact trusted hostname `ai-hive.iclip.cn`. - Uses an approved port and path. - Has not been redirected to another origin. Consequently, anyone who can influence the process environment or launch configuration can cause the script to transmit the credential to an arbitrary HTTP or HTTPS endpoint. Allowing endpoint customization is not necessary for the Skill’s declared use of the fixed AI-HIVE service and therefore exceeds the ...[truncated 1863 chars]- Remediation
View remediation
str: parsed = urlparse(url) if parsed.scheme != "https": raise SystemExit("The MCP endpoint must use HTTPS.") if parsed.hostname not in TRUSTED_HOSTS: raise SystemExit("The MCP endpoint host is not trusted.") if parsed.port not in (None, 443): raise SystemExit("The MCP endpoint must use port 443.") if parsed.path != "/api/mcp": raise SystemExit("The MCP endpoint path is not permitted.") if parsed.username or parsed.password or parsed.fragment: raise SystemExit("The MCP endpoint contains unsupported URL components.") return url ``` 3. **Disable redirects or validate every redirect destination.** Authentication headers must never be forwarded to a different origin. 4. **Bind credentials to the trusted origin.** Construct authentication headers only after the destination has passed validation. 5. **Prefer short-lived, narrowly scoped OAuth tokens** over long-lived API keys where supported. 6. **Document the override as dangerous or remove it from production builds.** If retained for testing, require an explicit development flag and refuse to send real credentials to non-production hosts. 7. **Revoke affected credentials** if the script has previously been run with an untrusted or unexpected `AI_HIVE_MCP_URL`. ]]>
