T09 · Insecure Skill Coding Practices
- Location
scripts/clawdos.py:19- Finding
Authenticated API traffic can be transmitted over plaintext HTTP
- Content
View full analysis
Vulnerability Details
File Location:
scripts/clawdos.py, lines 19-38
Vulnerability Type: Insecure transport of authentication credentials and privileged commands
Risk Level: HighTechnical Analysis
The client defaults to an unencrypted HTTP endpoint and does not require HTTPS when a non-loopback or remote address is configured. The API key is included in the
X-Api-Keyheader on authenticated requests.python BASE_URL = os.getenv("CLAWDOS_BASE_URL", "http://127.0.0.1:17171") API_KEY = os.getenv("CLAWDOS_API_KEY", "") TIMEOUT = int(os.getenv("CLAWDOS_TIMEOUT", "30")) FS_ROOT_ID = int(os.getenv("CLAWDOS_FS_ROOT_ID", "0")) def get_headers(auth=True): if auth: if not API_KEY: print(json.dumps({"error": "CLAWDOS_API_KEY environment variable is not set. Please configure the skill in OpenClaw."}), file=sys.stderr) sys.exit(1) return {"X-Api-Key": API_KEY} return {} def api_get(path, params=None, auth=True): url = f"{BASE_URL}{path}" resp = requests.get(url, params=params, headers=get_headers(auth), timeout=TIMEOUT) resp.raise_for_status() return resp def api_post(path, payload): url = f"{BASE_URL}{path}" resp = requests.post(url, json=payload, headers=get_headers(True), timeout=TIMEOUT) resp.raise_for_status() return resp.json()While plaintext HTTP over loopback may be acceptable under a narrow local-only deployment model, the Skill explicitly supports controlling a Windows host remotely. A user can configure
CLAWDOS_BASE_URLwith a remotehttp://address without any warning or refusal.In that configuration, a network-positioned attacker can observe the API key, command arguments, typed text, filesystem content, screenshots, and API responses. Base64 encoding used by the file-transfer functions is only a transport representation and provides no confidentiality.
The client also does not ...[truncated 1569 chars]
- Remediation
View remediation
Remediation Suggestions
- Require
https://for every non-loopbackCLAWDOS_BASE_URL. - Permit plaintext HTTP only through an explicit local-development option and only when the parsed hostname is a verified loopback address.
- Parse and validate the URL with
urllib.parse; reject embedded credentials, unexpected schemes, fragments, and malformed hostnames. - Emit a clear error rather than silently sending the API key over an insecure connection.
- Configure the server with a certificate issued by a trusted private or public CA. For high-value deployments, consider certificate or public-key pinning.
- Use short-lived, narrowly scoped credentials instead of a static bearer-equivalent API key where the service supports them.
- Separate capabilities into scoped credentials, particularly shell execution, screen capture, input control, and filesystem access.
- Add automated tests proving that remote HTTP URLs are rejected and that HTTPS certificate verification remains enabled.
- Document that Base64 is not encryption and must not be relied on to protect screenshots or file contents.
- Require
