T09 · Insecure Skill Coding Practices
- Location
list_devices.py:74- Finding
Bearer credential can be transmitted to an unrestricted gateway host
- Content
View full analysis
Vulnerability Details
File Location:
list_devices.py, lines 74–97
Vulnerability Type: Unrestricted credential destination
Risk Level: HighVulnerable Code
python def get_api_host(env_vars): """ 获取网关地址:~/.openclaw/.env 中的 AI_GATEWAY_HOST,未配置则用默认值。 """ host = env_vars.get("AI_GATEWAY_HOST") return host.rstrip("/") if host else DEFAULT_API_HOST def get_verify_ssl(env_vars): """ 判断是否启用 TLS 证书验证。默认启用。 仅当 ~/.openclaw/.env 中显式设置 AI_GATEWAY_VERIFY_SSL=false 时禁用(仅开发环境)。 """ val = env_vars.get("AI_GATEWAY_VERIFY_SSL", "true").lower() return val not in ("false", "0", "no") def call_device_list(api_key, api_host, verify_ssl): """ 调用 POST /api/device/list 获取设备列表。 # Returns * dict - 接口返回的完整 JSON 响应 """ url = f"{api_host}/api/device/list" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", } try: with httpx.Client(verify=verify_ssl, timeout=120.0, headers=headers) as client: resp = client.post(url, content=b"")Technical Analysis
AI_GATEWAY_HOSTis loaded from the shared configuration file and used directly to construct the request URL. The implementation does not validate:- That the scheme is HTTPS.
- That the hostname is the expected Closeli gateway.
- That the port is approved.
- That the URL excludes embedded user information or other unusual URL components.
- That the destination belongs to an explicit allowlist.
The same request carries
AI_GATEWAY_API_KEYin theAuthorizationheader. Consequently, anyone able to alter~/.openclaw/.env, including another Skill operating under the same user account, can redirect the credential to a server under their control.This exceeds the minimum privileges required for a device-list Skill. Its documented function requires access to one known API endpoin ...[truncated 1147 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove configurable production destinations if the Skill only supports one service.
- Hardcode
https://ai-open.icloseli.comas the credential-bearing origin. - If configurability is necessary, parse the URL with a standards-compliant URL parser and enforce:
httpsas the only permitted scheme.- An explicit hostname allowlist.
- Approved ports only.
- No embedded username or password.
- No fragments or unexpected path prefixes.
- Reject IP literals, loopback addresses, link-local addresses, and private-network destinations unless they are explicitly required.
- Configure redirect handling defensively and never forward
Authorizationheaders across origins. - Store the API key in a per-Skill secret store rather than a shared configuration file.
- Restrict the API key to device-list permission only and rotate any key that may have been exposed.
