T09 · Insecure Skill Coding Practices
- Location
- scripts/opencode_client.py:18
- Finding
- Unauthenticated Plaintext Transport for Privileged OpenCode API Operations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/opencode_client.py`, lines 18-45 **Vulnerability Type**: Unauthenticated and unencrypted remote API communication **Risk Level**: High ### Vulnerable Code ```python class OpenCodeClient: def __init__(self, base_url: str, proxy: Optional[str] = None): self.base_url = base_url.rstrip('/') self.proxy = proxy def _request(self, method: str, path: str, data: Optional[dict] = None) -> dict: url = f"{self.base_url}{path}" headers = {"Content-Type": "application/json"} req = urllib.request.Request( url, method=method, headers=headers, data=json.dumps(data).encode() if data else None ) # 配置代理 if self.proxy: proxy_handler = urllib.request.ProxyHandler({ 'http': self.proxy, 'https': self.proxy }) opener = urllib.request.build_opener(proxy_handler) urllib.request.install_opener(opener) try: with urllib.request.urlopen(req) as response: return json.loads(response.read().decode()) except urllib.error.HTTPError as e: return {"error": f"HTTP {e.code}: {e.reason}", "details": e.read().decode()} except Exception as e: return {"error": str(e)} ``` The client also exposes privileged server-side operations, including arbitrary shell-command requests: ```python def shell_command(self, session_id: str, command: str) -> dict: """在 session 中执行 shell 命令""" return self._request("POST", f"/session/{session_id}/shell", {"command": command}) ``` ### Technical Analysis The request layer only sends a `Content-Type` header. It provides no bearer token, API key, client certificate, request signature, or other authentication mechanism. It also accepts arbitrary base URLs without requiring HTTPS. The project docu ...[truncated 2247 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require `https://` endpoints by default and reject plaintext `http://` URLs unless the user supplies an explicit, prominently warned development-only override. 2. Add authenticated request support, preferably using short-lived bearer tokens, mutually authenticated TLS, or another server-supported authentication mechanism. 3. Retrieve credentials from protected environment variables, an operating-system credential store, or a dedicated secret manager. Do not place credentials in source code or session metadata. 4. Validate TLS certificates and hostnames. Do not introduce an option that silently disables certificate verification. 5. Apply server-side authorization independently of the client. Separate read-only session access from prompt submission, destructive session management, and shell execution. 6. Disable the shell endpoint unless it is explicitly required. If retained, require elevated authorization, explicit user confirmation, command restrictions, audit logging, and isolation in a low-privilege sandbox. 7. Add confirmation gates for destructive operations such as deletion, abortion, and shell execution. 8. Restrict network exposure of the OpenCode service through firewall rules, private networking, or an authenticated gateway. 9. Avoid globally installing a proxy opener with `urllib.request.install_opener`; use a client-specific opener so proxy behavior cannot unexpectedly affect unrelated requests in the process. ]]>
