T09 · Insecure Skill Coding Practices
- Location
scripts/call_api.py:41- Finding
API Credential Disclosure Through an Unrestricted or Unencrypted API Endpoint
- Content
View full analysis
dict[str, str]: return { "Content-Type": "application/json", "X-API-Key": env_required("FLIGHT_SCOUT_API_KEY"), } ``` ```python def request_json(method: str, path: str, *, body: dict | None = None, query: dict | None = None, idempotency_key: str | None = None) -> dict: base_url = env_required("FLIGHT_SCOUT_API_BASE_URL").rstrip("/") timeout = int(os.getenv("FLIGHT_SCOUT_API_TIMEOUT_SECONDS", "30")) url = f"{base_url}{path}" if query: url = f"{url}?{urlencode(query)}" headers = build_base_headers() if idempotency_key: headers["Idempotency-Key"] = idempotency_key data = None if body is None else json.dumps(body, ensure_ascii=False).encode("utf-8") req = Request(url, data=data, headers=headers, method=method.upper()) ``` ### Technical Analysis The client obtains `FLIGHT_SCOUT_API_BASE_URL` directly from the environment and uses it to construct the destination passed to `urllib.request.urlopen`. No validation is performed on the URL scheme, hostname, port, user-information component, or redirect destination. At the same time, `build_base_headers()` unconditionally places the value of `FLIGHT_SCOUT_API_KEY` in the `X-API-Key` request header. Consequently, every supported API operation sends the credential to whichever endpoint is specified by `FLIGHT_SCOUT_API_BASE_URL`. Although sending an API key is necessary for the Skill's declared authenticated API functionality, allowing the key to be sent to an unrestricted destination is not required. In particular: - An `http://` URL can expose the API key and flight-query data through plaintext network traffic. - A malicious or incorrectly configured host can directly collect the API key. - Red ...[truncated 2413 chars]- Remediation
View remediation
