T09 · Insecure Skill Coding Practices
Error
- Location
- runtime/crun_cli.py:199
- Finding
- API Key Disclosure Through Arbitrary and Insecure API Endpoints<![CDATA[ ## Vulnerability Details **File Location**: `runtime/crun_cli.py:199-241`, `runtime/crun_cli.py:582-592` **Vulnerability Type**: Credential exfiltration through an unvalidated destination **Risk Level**: High ### Technical Analysis The CLI accepts an unrestricted API base URL from either the `--base-url` argument or the `CRUN_BASE_URL` environment variable. It does not validate the scheme, hostname, port, or trust relationship before attaching the user's Crun API key to every request. Relevant code: ```python class CrunClient: def __init__( self, base_url: str, api_key: str, request_timeout: float = 30.0, request_retries: int = DEFAULT_REQUEST_RETRIES, ): if not api_key: raise CrunError("CRUN_API_KEY is required for remote commands") if request_retries < 0: raise CrunError("request_retries must be zero or greater") self.base_url = base_url.rstrip("/") self.api_key = api_key self.request_timeout = request_timeout self.request_retries = request_retries def request( self, method: str, path: str, *, query: Optional[dict[str, Any]] = None, body: Optional[dict[str, Any]] = None, retry: bool = True, ) -> Any: url = f"{self.base_url}{path}" if query: filtered = {key: value for key, value in query.items() if value is not None} if filtered: url = f"{url}?{urlencode(filtered)}" data = json.dumps(body).encode("utf-8") if body is not None else None request = Request( url, data=data, method=method, headers={ "Accept": "application/json", "Content-Type": "application/json", "X-API-KEY": self.api_key, "User-Agent": "crun-agent-skills/1", }, ) attempts = self.request_retries ...[truncated 2607 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Allowlist the official service origins: - `https://api.crun.ai` - `https://api.crunai.com` 2. Require HTTPS for any endpoint that receives an API key. 3. If custom endpoints are genuinely required, require an explicit high-friction option such as `--allow-custom-api-origin`, display the resolved origin, and request user confirmation before sending credentials. 4. Reject URLs containing user information, fragments, unexpected paths, or nonstandard schemes. 5. Compare the parsed hostname rather than relying on string prefixes. 6. Do not attach `X-API-KEY` after a redirect to a different origin. Either disable redirects for authenticated requests or revalidate every redirect target and strip credentials on cross-origin redirects. 7. Separate development credentials from production credentials so custom testing endpoints cannot receive the primary account key. 8. Add tests covering HTTP URLs, lookalike domains, embedded credentials, alternate ports, redirects, IPv4/IPv6 literals, and environment-variable endpoint overrides. ]]>
