T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/openclaw_trent/lib/trent_client.py:33
- Finding
- Configurable API endpoints can disclose the Trent API key to an arbitrary server<![CDATA[ ## Vulnerability Details **File Location**: `scripts/openclaw_trent/lib/trent_client.py:33-37`, `scripts/openclaw_trent/lib/trent_client.py:142-163`, and `scripts/openclaw_trent/lib/trent_client.py:259-274` **Vulnerability Type**: Unvalidated authenticated API endpoint **Risk Level**: High ### Vulnerable Code ```python def _get_chat_url() -> str: return os.environ.get("TRENT_CHAT_API_URL") or _DEFAULT_CHAT_URL def _get_agent_url() -> str: return os.environ.get("TRENT_AGENT_API_URL") or _DEFAULT_AGENT_URL ``` The configurable URL is subsequently used with the Trent API key: ```python headers = { "Authorization": auth_header, "Content-Type": "application/json", "Accept": "text/event-stream", } req = urllib.request.Request( f"{_get_chat_url()}/v1/chat", data=payload, headers=headers, method="POST", ) ``` The same issue affects agent API requests: ```python def _api_request(method: str, endpoint: str, json_data: dict | None = None) -> dict: auth_header = _get_auth_header() url = f"{_get_agent_url()}/v1/trent-agent{endpoint}" payload = json.dumps(json_data).encode() if json_data is not None else None headers: dict[str, str] = { "Authorization": auth_header, "Content-Type": "application/json", } req = urllib.request.Request(url, data=payload, headers=headers, method=method) with urllib.request.urlopen(req, timeout=60) as resp: data = json.loads(resp.read().decode()) ``` ### Technical Analysis Both API base URLs are taken directly from environment variables. Although `_is_trusted_trent_url()` exists elsewhere in the module, it is not applied to `TRENT_CHAT_API_URL` or `TRENT_AGENT_API_URL`. Consequently, a party capable of influencing the audit process's environment can redirect authenticated requests to an arbitrary endpoint. The `Authorization` header containing `TRENT_API_KEY` is attached before the request is sent. The chat request can additionally expose ...[truncated 1525 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate both configured base URLs before attaching credentials: - Require the `https` scheme. - Reject user information, fragments, malformed ports, and empty hostnames. - Restrict hosts to an explicit allowlist such as `trent.ai` and approved subdomains. 2. Call the existing `_is_trusted_trent_url()` function from `_get_chat_url()` and `_get_agent_url()`, failing closed when validation fails. 3. Normalize URLs with `urllib.parse.urlparse()` rather than relying on string concatenation. 4. Disable automatic cross-origin redirects for authenticated requests, or verify every redirect target before forwarding credentials. 5. If self-hosted or development endpoints must be supported, use separate endpoint-specific credentials rather than the production Trent API key. 6. Require explicit user confirmation when a non-default endpoint is selected and display the normalized destination hostname. 7. Add tests covering HTTP URLs, user-information URLs, lookalike domains, fragments, alternate ports, redirects, and attacker-controlled hosts. A hardened pattern would be: ```python def _validated_base_url(env_name: str, default: str) -> str: url = (os.environ.get(env_name) or default).strip().rstrip("/") if not _is_trusted_trent_url(url): raise RuntimeError(f"Untrusted API endpoint configured in {env_name}") return url ``` ]]>
