T09 · Insecure Skill Coding Practices
Error
- Location
- clawswap/runtime_client.py:237
- Finding
- Bearer credentials can be transmitted to an arbitrary or plaintext gateway<![CDATA[ ## Vulnerability Details **File Location**: `clawswap/runtime_client.py`, lines 237-248 and 848-870 **Vulnerability Type**: Unrestricted credential transmission endpoint **Risk Level**: High ### Vulnerable Code ```python def http_json(method, url, data=None, token=None, timeout=15): """Send an HTTP request and return (status_code, response_body_dict | None).""" headers = { "Content-Type": "application/json", "User-Agent": "ClawSwap-RuntimeClient/1.0", } if token: headers["Authorization"] = f"Bearer {token}" body = json.dumps(data).encode() if data else None req = Request(url, data=body, headers=headers, method=method) try: with urlopen(req, timeout=timeout) as resp: return resp.status, json.load(resp) ``` ```python env_files = [ os.path.join(SKILL_DIR, ".env"), os.path.join(SKILL_DIR, "..", "..", "gateway", "tests", ".env.e2e"), ] for env_file in env_files: if os.path.exists(env_file): with open(env_file) as f: for line in f: line = line.strip() if line and not line.startswith("#") and "=" in line: k, _, v = line.partition("=") if v and k.strip() not in os.environ: os.environ[k.strip()] = v.strip() saved = load_saved_token() or {} api_key = args.api_key or os.environ.get("CLAWSWAP_API_KEY") or load_api_key() agent_id = args.agent_id or os.environ.get("CLAWSWAP_AGENT_ID") or saved.get("agent_id") gateway_url = args.gateway or os.environ.get("CLAWSWAP_GATEWAY_URL") or os.environ.get("GATEWAY_URL") or saved.get("gateway_url", "https://api.clawswap.trade") bootstrap_token = args.bootstrap_token or os.environ.get("CLAWSWAP_BOOTSTRAP_TOKEN") runtime_token = args.runtime_token or os.environ.get("CLAWSWAP_RUNTIME_TOKEN") or saved.get("runtime_token") ``` ### Technical Analysis The shared HTTP function places API keys, bootstrap tokens, and runtime tokens in ...[truncated 2041 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require `https://` for every non-loopback gateway. 2. Default to an exact allowlist containing `https://api.clawswap.trade`. 3. Reject embedded URL credentials, unexpected schemes, fragments, and unapproved ports. 4. Remove the generic `GATEWAY_URL` fallback and retain only the Skill-specific `CLAWSWAP_GATEWAY_URL`. 5. Require an explicit development option such as `--allow-custom-gateway` before sending credentials to a non-production origin. 6. Display the normalized credential destination and obtain confirmation before first use of a custom gateway. 7. Never permit plaintext HTTP except for explicitly approved loopback test addresses. 8. Bind saved credentials to the origin for which they were issued. Refuse to reuse a saved token if the configured origin changes. 9. Add tests confirming rejection of HTTP, malformed URLs, credential-bearing URLs, and unauthorized domains. ]]>
