T09 · Insecure Skill Coding Practices
- Location
scripts/run_generic_fto_report.py:661- Finding
Configurable API Base URL Can Exfiltrate the PatSnap Bearer Credential
- Content
View full analysis
PatSnapClient: config = load_json(config_path, expected=dict) if config_path.exists() else {} key = api_key or os.getenv("PATSNAP_API_KEY") or clean_text(config.get("api_key")) if not key: raise ValueError("PatSnap API key missing. Set PATSNAP_API_KEY or pass --api-key; never place secrets in reports.") return PatSnapClient( api_key=key, base_url=clean_text(config.get("base_url")) or "https://connect.patsnap.com", connect_timeout=float(config.get("connect_timeout_seconds", 10)), read_timeout=float(config.get("read_timeout_seconds", config.get("timeout_seconds", 60))), max_retries=int(config.get("max_retries", 3)), ) ``` The resulting client accepts any absolute HTTPS host: ```python parsed = urlparse(str(base_url or "")) if parsed.scheme.lower() != "https" or not parsed.netloc: raise ValueError("PatSnap base URL must be an absolute HTTPS URL.") self._api_key = key self.base_url = f"{parsed.scheme}://{parsed.netloc}".rstrip("/") ``` Every request then sends the credential to that host: ```python def _headers(self, *, accept: str = "application/json") -> dict[str, str]: return { "Authorization": f"Bearer {self._api_key}", "Accept": accept, "Content-Type": "application/json", "User-Agent": "PatSnap-FTO-Screening-Skill/2.0", } ``` ### Technical Analysis The configuration restricts the URL scheme to HTTPS but does not restrict the hostname to an approved PatSnap domain. HTTPS protects transport confidentiality but does not establish that the destination is trusted. The CLI also permits an arbitrary `--api-config` path. Consequently, a mali ...[truncated 2196 chars]- Remediation
View remediation
