T09 · Insecure Skill Coding Practices
Warning
- Location
- src/search.py:102
- Finding
- API Credentials May Be Disclosed Through HTTP Error Logging<![CDATA[ ## Vulnerability Details **File Location**: `src/search.py:102-110`, `src/search.py:155-170`, and `src/search.py:217-241` **Vulnerability Type**: API credential exposure through unsanitized exception logging **Risk Level**: Medium ### Vulnerable Code ```python # GoogleSearch.search params = { 'q': query, 'key': self.api_key, 'cx': self.cx, 'num': min(count, 10) # API max is 10 per request } response = requests.get(self.base_url, params=params, timeout=30) response.raise_for_status() ``` ```python # BaiduSearch.search url = f"{self.base_url}/v1/search" params = { 'query': query, 'count': count, 'ak': self.api_key } headers = { 'Content-Type': 'application/json' } response = requests.get(url, params=params, headers=headers, timeout=30) response.raise_for_status() ``` ```python if selected_engine == 'google' and self.google: try: google_results = self.google.search(query, count) results.extend(google_results) except Exception as e: print(f"⚠️ Google search failed: {e}") elif selected_engine == 'baidu' and self.baidu: try: baidu_results = self.baidu.search(query, count) results.extend(baidu_results) except Exception as e: print(f"⚠️ Baidu search failed: {e}") elif selected_engine == 'both': # Search both engines if self.google: try: google_results = self.google.search(query, count) results.extend(google_results) except Exception as e: print(f"⚠️ Google search failed: {e}") if self.baidu: try: baidu_results = self.baidu.search(query, count) results.extend(baidu_results) except Exception as e: print(f"⚠️ Baidu search failed: {e}") ``` ### Technical Analysis The Google and Baidu API credentials are supplied as URL query parameters named `key` and `ak`. When `raise_for_status()` raises a `requests` HTTP exception, the exception representa ...[truncated 1755 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not print raw `requests` exceptions for requests containing credentials. 2. Log only explicitly selected, non-sensitive fields such as the provider name and HTTP status code. 3. Redact sensitive query parameters including `key`, `ak`, `token`, `access_token`, and similar credential names before logging URLs. 4. Where supported by the provider, transmit credentials in an authorization header rather than in the URL. 5. Configure API keys with least-privilege provider restrictions, including API allowlists, source restrictions, and conservative quotas. 6. Ensure production logging systems do not retain query strings containing secrets. 7. Rotate any credentials that may already have appeared in logs. For example: ```python except requests.HTTPError as exc: status = exc.response.status_code if exc.response is not None else "unknown" print(f"Google search failed with HTTP status {status}") except requests.RequestException: print("Google search failed due to a network error") ``` Apply equivalent sanitized handling to the Baidu branch and avoid exposing response bodies unless they have also been reviewed and redacted. ]]>
