T09 · Insecure Skill Coding Practices
- Location
src/sherpamind/client.py:40- Finding
Configurable API Endpoint Can Exfiltrate SherpaDesk Credentials
- Content
View full analysis
dict[str, str]: credentials = f"{self._auth_identity()}:{self.api_key}".encode("utf-8") encoded = base64.b64encode(credentials).decode("ascii") headers = { "Accept": "application/json", "Authorization": f"Basic {encoded}", } if self.api_user: headers["X-API-User"] = self.api_user return headers def _build_url(self, path: str) -> str: return f"{self.api_base_url.rstrip('/')}/{path.lstrip('/')}" @retry( stop=stop_after_attempt(4), wait=wait_exponential(multiplier=1, min=1, max=16), retry=retry_if_exception_type(httpx.HTTPError), reraise=True, ) def get(self, path: str, params: dict[str, Any] | None = None) -> Any: self.pacer.wait() try: with httpx.Client(timeout=self.timeout_seconds, headers=self._build_headers()) as client: response = client.get(self._build_url(path), params=params) ``` The destination is loaded without validation: ```python api_base_url=_env_or_file( "SHERPADESK_API_BASE_URL", file_values, "https://api.sherpadesk.com", ) or "https://api.sherpadesk.com", api_key=os.getenv("SHERPADESK_API_KEY") or _read_secret_file(paths.api_key_file), api_user=os.getenv("SHERPADESK_API_USER") or _read_secret_file(paths.api_user_file), ``` It can also be persisted through the CLI: ```python settings_file = stage_connection_settings( api_base_url=api_base_url, org_key=org_key, instance_key=instance_key, notify_channel=notify_channel, ) ``` ### Technical Analysis The client constructs an HTTP Basic Authorization header containing the API identity and API key, then sends it to the configurable `api_base_ ...[truncated 1791 chars]- Remediation
View remediation
