T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/mercadolibre_review_search.py:55
- Finding
- Unrestricted API origin permits sensitive requests to attacker-controlled or plaintext endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mercadolibre_review_search.py:55-63`, `scripts/mercadolibre_site_list.py:62-68`, `scripts/geekbi_auth.py:578-580`, and `scripts/geekbi_auth.py:700-716` **Vulnerability Type**: Arbitrary authentication and API origin with no HTTPS or hostname validation **Risk Level**: High ### Vulnerable Code ```python # scripts/mercadolibre_review_search.py:55-63 parser.add_argument("--base-url", default=DEFAULT_BASE_URL) parser.add_argument("--param", action="append", default=[], help="名称=值;必须传 goodsId") 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/mercadolibre_site_list.py:62-68 parser.add_argument("--base-url", default=DEFAULT_BASE_URL) parser.add_argument("--timeout", type=float, default=30) args = parser.parse_args() try: payload = authenticated_json_request( f"{args.base_url.rstrip('/')}{ENDPOINT}", args.base_url, args.timeout ) ``` ```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:700-716 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: response_payload = _read_json_response(response) _raise_action_if_needed(response_payload) return response_payload ``` ### Technical Analysis The two public query scripts accept an unrestricted `-- ...[truncated 2670 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `--base-url` from production-facing commands if only the declared GeekBI service is required. 2. Otherwise, parse the URL and enforce an exact allowlist containing only the approved origin, such as `https://openapi.geekbi.com`. 3. Require HTTPS and reject: - HTTP and all non-HTTPS schemes. - Embedded usernames or passwords. - Unexpected ports. - Fragments. - Ambiguous, malformed, loopback, private-network, or link-local hosts. 4. Canonicalize the approved origin before using it as an authentication-state key. 5. Ensure the final API request origin exactly matches the validated authentication origin. 6. Disable cross-origin redirects for requests carrying authentication headers. Revalidate every redirect target before following it. 7. Validate authentication `jumpUrl` values against a separate allowlist of approved HTTPS login origins before displaying them. 8. Place the bearer value in the API’s documented authentication header and ensure it is never forwarded across origins. 9. Add automated tests covering HTTP URLs, deceptive hostnames, embedded credentials, alternate ports, redirects, loopback addresses, and private-network destinations. ]]>
