T09 · Insecure Skill Coding Practices
- Location
scripts/matic.py:20- Finding
Unrestricted API Base URL Can Disclose Bearer Credentials and User Prompts
- Content
View full analysis
str: raw = os.environ.get("MATIC_TRADES_API_BASE", "https://api.matictrades.com/api/v1").strip().rstrip("/") return raw ``` ```python def _post(path: str, body: Dict[str, Any]) -> Dict[str, Any]: url = f"{_base_url()}{path}" data = json.dumps(body).encode("utf-8") req = urllib.request.Request( url, data=data, method="POST", headers={ "Authorization": f"Bearer {_api_key()}", "Content-Type": "application/json", "Accept": "application/json", }, ) ``` ### Technical Analysis The `MATIC_TRADES_API_BASE` environment variable is used directly to construct the destination URL without validating its scheme, hostname, port, user-information component, or trust level. Every request to this destination includes the Matic Trades bearer token and the user-provided prompt. Consequently, a party capable of modifying the skill's environment or deployment configuration can set the variable to an attacker-controlled server. The script will then transmit the API key and prompt to that server. It also accepts plaintext `http://` destinations, which can expose the same data to network interception. This is a configuration-dependent vulnerability: exploitation requires influence over the environment or configuration from which the skill runs. It does not independently grant an attacker the ability to change that environment. ### Attack Path 1. An attacker gains the ability to alter the OpenClaw deployment environment, launch configuration, shell profile, or other source of `MATIC_TRADES_API_BASE`. 2. The attacker assigns an untrusted destination, for example: ```bash export MATIC_TRADES_API_BASE= ...[truncated 1479 chars]- Remediation
View remediation
str: raw = os.environ.get( "MATIC_TRADES_API_BASE", "https://api.matictrades.com/api/v1", ).strip().rstrip("/") parsed = urlsplit(raw) if parsed.scheme != "https": raise ValueError("MATIC_TRADES_API_BASE must use HTTPS") if parsed.username or parsed.password: raise ValueError("Embedded URL credentials are not allowed") if parsed.fragment or parsed.query: raise ValueError("Query strings and fragments are not allowed") if parsed.hostname not in OFFICIAL_HOSTS: raise ValueError("Untrusted Matic Trades API host") return raw ``` For legitimate self-hosted deployments, replace the fixed set with an administrator-controlled allowlist while retaining HTTPS and origin validation. ]]>
