T09 · Insecure Skill Coding Practices
Warning
- Location
- caipiao.py:19
- Finding
- API Credential Exposed in URL Query String## Vulnerability Details **File Location**: `caipiao.py`, lines 19–23 **Vulnerability Type**: API credential exposure through URL query parameters **Risk Level**: Medium ### Vulnerable Code ```python all_params = {"appkey": appkey} all_params.update({k: v for k, v in params.items() if v not in (None, "")}) url = f"{BASE_URL}/{path}" try: resp = requests.get(url, params=all_params, timeout=10) ``` ### Technical Analysis The `JISU_API_KEY` value is inserted into `all_params` as `appkey` and passed to `requests.get` through the `params` argument. The Requests library serializes these parameters into the request URL, producing a request resembling: ```text https://api.jisuapi.com/caipiao/query?appkey=SECRET_VALUE&caipiaoid=13 ``` TLS protects the URL while it travels between the client and the HTTPS endpoint. However, URL query strings can be retained in HTTP client diagnostics, reverse-proxy logs, API gateway logs, server access logs, monitoring platforms, and error reports. Consequently, personnel or systems with access to those records may also obtain the credential. Exploitation requires access to infrastructure or diagnostic records that capture the complete request URL. There is no evidence that this skill itself writes the URL to local logs. ### Attack Path 1. A user configures a valid API credential in the `JISU_API_KEY` environment variable. 2. The skill copies that credential into the `appkey` query parameter. 3. `requests.get` transmits a URL containing the credential to the external API. 4. A proxy, gateway, API server, monitoring service, or diagnostic facility records the complete URL. 5. An attacker or unauthorized operator with access to those records extracts the API key. 6. The attacker submits requests to JisuAPI using the exposed key until it is revoked, expires, or reaches its usage limit. ### Impact Assessment Successful exploitation does not grant local system privileges ...[truncated 472 chars]
- Remediation
- ## Remediation Suggestions 1. Use an authorization header instead of a URL parameter if JisuAPI supports header-based authentication: ```python headers = {"Authorization": f"Bearer {appkey}"} resp = requests.get(url, params=params, headers=headers, timeout=10) ``` 2. If the provider supports POST authentication, place the credential in the request body rather than the URL. 3. If JisuAPI mandates the `appkey` query parameter, configure clients, proxies, gateways, servers, and observability platforms to redact `appkey` values and avoid recording full query strings. 4. Use a dedicated key with the minimum required API permissions and conservative request or spending limits. 5. Rotate the key periodically and immediately rotate any key suspected of appearing in logs. 6. Restrict the key by source IP, permitted endpoint, or service scope when the provider offers those controls. 7. Document that query-string authentication is provider-mandated and warn operators not to enable verbose HTTP logging in production.
