T09 · Insecure Skill Coding Practices
- Location
scripts/exchange_rate.py:28- Finding
API Credential Transmitted in a Plaintext HTTP Query String
- Content
View full analysis
dict: """发起 HTTP GET 请求""" full_url = f"{url}?{urllib.parse.urlencode(params)}" try: with urllib.request.urlopen(full_url, timeout=15) as resp: return json.loads(resp.read().decode("utf-8")) except Exception as e: return {"error_code": -1, "reason": f"网络请求失败: {e}"} ``` ```python def query_currency_list(api_key: str) -> dict: """查询支持的货币列表""" data = _request(LIST_API_URL, {"key": api_key}) ``` ```python data = _request(CURRENCY_API_URL, { "key": api_key, "from": from_curr, "to": to_curr, }) ``` ### Technical Analysis The Skill must communicate with the declared Juhe exchange-rate service to perform its intended function. Sending the API key to that service is therefore functionally necessary. However, both API endpoints use plaintext HTTP, and `_request()` places the credential in the URL query string. HTTP provides neither transport confidentiality nor server authentication. Any network observer or active intermediary between the host and the API service—including a compromised router, public Wi-Fi operator, transparent proxy, gateway, or malicious DNS/network operator—can read the API key and currency parameters. An active intermediary can also modify the response because its integrity is not protected. Placing the key in the URL creates additional exposure because complete URLs may be retained by proxies, network monitoring systems, access logs, or diagnostic tooling. This exceeds the minimum privilege necessary for the Skill: the key only needs to be disclosed securely to the intended API provi ...[truncated 1518 chars]- Remediation
View remediation
