T09 · Insecure Skill Coding Practices
- Location
scripts/vehicle_plate_query.py:24- Finding
Unrestricted API Endpoint Override Can Expose AppKey and Vehicle Plate Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/vehicle_plate_query.py, lines 24 and 100–114
Vulnerability Type: Unvalidated API destination and sensitive credentials in URL query parameters
Risk Level: MediumVulnerable Code
python API_BASE_URL = os.environ.get("JIKE_API_BASE_URL", "https://api.jikeapi.cn").rstrip("/") API_PATH = "/v1/vehicle/plate/query" APPKEY_ENV_NAMES = ("JIKE_VEHICLE_PLATE_QUERY_KEY", "JIKE_APPKEY")python def request_api(plate_number: str, appkey: str) -> dict[str, Any]: """ 功能说明: 1. 调用即刻数据车牌号码归属地接口。 2. 使用 `plate_number` 和 `appkey` 查询参数。 3. 返回接口 JSON;网络异常时返回统一错误结构。 @param plate_number 车牌号码或车牌前缀 @param appkey 即刻数据 AppKey @return dict 接口返回或错误结构 """ url = f"{API_BASE_URL}{API_PATH}?{urllib.parse.urlencode({'plate_number': plate_number, 'appkey': appkey})}" try: with urllib.request.urlopen(url, timeout=15) as response: return json.loads(response.read().decode("utf-8"))Technical Analysis
The API base URL is obtained from the undeclared
JIKE_API_BASE_URLenvironment variable without validating its scheme or hostname. Although the default value points to the documented official HTTPS service, an inherited or attacker-controlled process environment can redirect requests to an arbitrary HTTP or HTTPS server.The request includes both the AppKey and queried vehicle plate number in the URL query string. Consequently, redirection to an attacker-controlled endpoint directly discloses both values. Even when the official endpoint is used, query-string credentials can be retained in web server, reverse-proxy, monitoring, or diagnostic logs.
This is not evidence of intentional exfiltration: the default destination is consistent with
SKILL.mdand_meta.json. The issue is an insecure configuration and credential-transmission pattern that becomes exploitable when an attacker can influence the execution environment.Attack Path
- An attac ...[truncated 1712 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove the runtime endpoint override in production and use the fixed official endpoint:
python API_BASE_URL = "https://api.jikeapi.cn" -
If endpoint configurability is required for testing, parse and strictly validate it:
- Require the
httpsscheme. - Allow only an explicit hostname allowlist, such as
api.jikeapi.cn. - Reject embedded credentials, fragments, unexpected ports, and malformed hosts.
- Keep test endpoint configuration unavailable in production builds.
- Require the
-
Prefer transmitting the AppKey in an authorization header rather than the URL if supported by the API:
python request = urllib.request.Request(url_without_appkey) request.add_header("Authorization", f"Bearer {appkey}") -
If the provider mandates query-string authentication, ensure URLs are never printed or included in exceptions and configure proxies, servers, and monitoring systems to redact the
appkeyparameter. -
Deprecate the
--keyoption because command-line arguments may be visible in shell history and process listings. Prefer a protected environment variable or secret manager. -
Restrict access to
scripts/.env, exclude it from source control and packaged artifacts, and document secure file permissions. -
Add tests confirming that plaintext HTTP URLs, unapproved hosts, and redirect attempts to unapproved destinations are rejected. Consider disabling automatic cross-origin redirects or validating the final redirect destination before transmitting credentials.
-
