T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/eodhd_client.py:37
- Finding
- API Token Disclosed in Error Return Values## Vulnerability Details **File Location**: `scripts/eodhd_client.py`, lines 37-48 **Vulnerability Type**: Sensitive credential exposure through error handling **Risk Level**: Medium **Complete Code Snippet**: ```python def _get_request(self, endpoint, params=None): '''Helper function to make a GET request to the API.''' if params is None: params = {} params['api_token'] = self.api_token params['fmt'] = 'json' url = f"{self.base_url}/{endpoint}" try: response = requests.get(url, params=params) response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx) return response.json() except requests.exceptions.RequestException as e: return {"error": str(e), "url": url, "params": params} ``` ### Technical Analysis The method inserts the EODHD API token into the mutable `params` dictionary and returns that entire dictionary when a network or HTTP error occurs. Consequently, every returned error object contains the plaintext token under `params["api_token"]`. The Skill instructions direct callers to check for an `error` field and report errors to the user. A caller that serializes, prints, logs, or otherwise exposes the complete error object can therefore disclose the credential. Authentication is necessary for the API request, but including the credential in diagnostic output is not necessary and exceeds minimum disclosure requirements. ### Attack Path 1. A valid EODHD token is loaded from configuration or passed to `EODHDClient`. 2. A request fails because of an HTTP error, connectivity problem, TLS error, timeout, or deliberately invalid request. 3. The exception handler returns `params`, which contains the plaintext `api_token`. 4. Agent code, application logging, telemetry, debugging output, or a user-facing response serializes the returned dictionary. 5. A party with access to that output obtains the token an ...[truncated 492 chars]
- Remediation
- ## Remediation Suggestions - Never return authentication parameters in error objects. - Construct a sanitized diagnostic dictionary and replace the token with a fixed value such as `[REDACTED]`. - Prefer returning only an error type, a concise message, and an HTTP status code. - Ensure application logs and Agent responses apply credential redaction as a defense-in-depth measure. - Avoid mutating a caller-supplied parameter dictionary when adding authentication data. Example: ```python request_params = dict(params or {}) request_params["api_token"] = self.api_token request_params["fmt"] = "json" try: response = requests.get(url, params=request_params, timeout=30) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: return { "error": str(e), "url": url, "params": { key: ("[REDACTED]" if key == "api_token" else value) for key, value in request_params.items() }, } ```
