T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/coupang_goods_search.py:64
- Finding
- Unrestricted API Origin Permits Insecure Authentication and Attacker-Controlled Login Flows<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/coupang_goods_search.py:64-73` - `scripts/coupang_goods_info.py:40-50` - `scripts/coupang_site_list.py:58-65` - `scripts/coupang_search_common.py:108-111` - `scripts/geekbi_auth.py:578-580` - `scripts/geekbi_auth.py:698-721` **Vulnerability Type**: Unvalidated network destination and insecure transport configuration **Risk Level**: Medium ### Vulnerable Code ```python # scripts/coupang_goods_search.py:64-73 parser = argparse.ArgumentParser(description="查询 Coupang 商品并输出 JSON") parser.add_argument("--base-url", default=DEFAULT_BASE_URL) parser.add_argument("--param", action="append", default=[], help="查询条件,格式为 名称=值") parser.add_argument("--timeout", type=float, default=30) args = parser.parse_args() try: params = parse_params(args.param) payload = authenticated_json_request( build_url(args.base_url, ENDPOINT, params), args.base_url, args.timeout ) ``` ```python # scripts/coupang_search_common.py:108-111 def build_url(base_url, endpoint, params): url = f"{base_url.rstrip('/')}{endpoint}" query = urlencode(params) return f"{url}?{query}" if query else url ``` ```python # scripts/geekbi_auth.py:578-580 endpoint = f"{base_url.rstrip('/')}{TOKEN_ENDPOINT}" try: response = _post_json(endpoint, {"deviceCode": pending["deviceCode"]}, timeout) ``` ```python # scripts/geekbi_auth.py:698-721 def authenticated_json_request( url, base_url, timeout, *, method="GET", body=None, headers=None, ): complete_pending_login(base_url, timeout) request_headers = _api_headers() if headers: request_headers.update(headers) authorization = _authorization_header(base_url) if authorization: request_headers["token"] = authorization request = Request( url, data=body, headers=request_headers, method=method, ) try: with urlopen(request, timeout=timeout) as response: r ...[truncated 3401 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `--base-url` from production-facing CLIs and use the fixed GeekBI HTTPS origin. 2. If alternate origins are required for testing, place the option behind an explicit development-mode flag that is disabled by default. 3. Parse destinations with `urllib.parse.urlsplit` and enforce all of the following: - Scheme must be `https`. - Host must match an explicit allowlist, preferably only `openapi.geekbi.com`. - User information, query strings, and fragments must not be present in the base URL. - Ports must be restricted to approved HTTPS ports. - Loopback, private, link-local, multicast, and unspecified IP addresses must be rejected. 4. Resolve hostnames safely and account for DNS rebinding before connecting to non-fixed destinations. 5. Validate every server-provided `jumpUrl` against a separate allowlist of approved HTTPS authentication origins before returning it to the user. 6. Do not permit redirects to a different origin during authenticated requests. Revalidate the destination after every redirect or disable automatic redirects. 7. Use the standard `Authorization: Bearer ...` header unless the API contract explicitly requires the custom `token` header. 8. Add tests covering HTTP URLs, embedded credentials, alternate domains, localhost, private IP ranges, IPv6 loopback, malformed URLs, malicious login URLs, and cross-origin redirects. ]]>
