T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/mercadolibre_search_common.py:107
- Finding
- Unrestricted API Base URL Allows Authentication Traffic to Be Redirected to Untrusted or Insecure Origins<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mercadolibre_search_common.py:11,107-110`; `scripts/geekbi_auth.py:564-579,698-721`; query scripts exposing `--base-url`, including `scripts/mercadolibre_goods_search.py:62-70` **Vulnerability Type**: Unvalidated authentication destination and insecure transport **Risk Level**: High ### Vulnerable Code ```python # scripts/mercadolibre_search_common.py:11 DEFAULT_BASE_URL = "https://openapi.geekbi.com" ``` ```python # scripts/mercadolibre_search_common.py:107-110 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:564-579 def complete_pending_login(base_url, timeout): payload = _load_state() server_key = _server_key(base_url) server = payload["servers"].get(server_key) if not isinstance(server, dict): return False now = int(time.time()) changed = _clear_expired(server, now) pending = server.get("pending") if not isinstance(pending, dict): if changed: _persist_expiry_cleanup(server_key, now) return False 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: ``` ```pyth ...[truncated 3955 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `--base-url` from production-facing query commands unless custom endpoints are a documented requirement. 2. Enforce an explicit origin allowlist, preferably only: - Scheme: `https` - Host: `openapi.geekbi.com` - Default HTTPS port 3. Parse URLs with `urllib.parse.urlsplit` rather than validating them through string matching. 4. Reject URLs containing user information, fragments, unexpected ports, malformed hostnames, or non-root path prefixes. 5. Ensure the API request URL and authentication base URL resolve to the same canonical approved origin. 6. Disable redirects for authenticated requests or implement a redirect handler that rejects every cross-origin redirect. 7. Never forward the `token` header after a redirect unless the destination is the same validated origin. 8. Validate server-provided action URLs before presenting them to users. Require HTTPS and an explicitly approved authentication hostname. 9. Add automated tests covering HTTP URLs, unknown hosts, embedded credentials, deceptive hostname suffixes, unexpected ports, and cross-origin redirects. ]]>
