T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/capture_and_download.py:30
- Finding
- Unrestricted API Endpoint Receives Sensitive Authentication Metadata<![CDATA[ ## Vulnerability Details **File Location**: `scripts/capture_and_download.py:30-54` and `scripts/capture_and_download.py:72-77` **Vulnerability Type**: Improper validation of a security-sensitive network destination **Risk Level**: High ### Vulnerable Code ```python # API base address JF_ENDPOINT = os.getenv("JF_ENDPOINT", "api-cn.jftechws.com") JF_BASE_URL = f"https://{JF_ENDPOINT}/gwp/v3" def get_headers(uuid: str, app_key: str, app_secret: str, move_card: int) -> Dict[str, str]: """Generate request headers containing the signature and timestamp.""" time_millis = get_time_millis() signature = generate_signature(uuid, app_key, app_secret, time_millis, move_card) return { "Content-Type": "application/json; charset=UTF-8", "uuid": uuid, "appKey": app_key, "timeMillis": time_millis, "signature": signature, "X-Request-Id": os.urandom(16).hex() } def get_device_tokens(device_sns: List[str], uuid: str, app_key: str, app_secret: str, move_card: int) -> Dict[str, str]: """Retrieve device tokens and return an SN-to-token mapping.""" url = f"{JF_BASE_URL}/rtc/device/token" headers = get_headers(uuid, app_key, app_secret, move_card) body = {"sns": device_sns, "accessToken": ""} response = requests.post(url, headers=headers, json=body, timeout=30) ``` The same unvalidated base URL is also used by `device_capture()`: ```python url = f"{JF_BASE_URL}/rtc/device/capture/{device_token}" headers = get_headers(uuid, app_key, app_secret, move_card) ... response = requests.post(url, headers=headers, json=body, timeout=30) ``` ### Technical Analysis `JF_ENDPOINT` is accepted directly from the process environment and interpolated into an HTTPS URL without checking whether the hostname belongs to the documented JF service. Requests to this endpoint contain the user's UUID, application key, timestamp, request identifier, device serial numbers, and a signatur ...[truncated 1781 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace the free-form endpoint with a region selector mapped to fixed hosts: ```python ALLOWED_ENDPOINTS = { "CN": "api-cn.jftechws.com", "AS": "api-as.jftechws.com", "EU": "api-eu.jftechws.com", "NA": "api-na.jftechws.com", } region = os.getenv("JF_REGION", "CN").upper() if region not in ALLOWED_ENDPOINTS: raise ValueError("Unsupported JF region") JF_BASE_URL = f"https://{ALLOWED_ENDPOINTS[region]}/gwp/v3" ``` 2. If custom endpoints are operationally necessary, parse them with `urllib.parse` and reject user information, ports, IP literals, non-HTTPS schemes, and hosts outside an explicit allowlist. 3. Do not follow redirects for authenticated API requests, or validate every redirect target against the same allowlist. 4. Ensure errors and diagnostics never log headers, signatures, secrets, or full request objects. 5. Rotate credentials if signed requests have already been sent to an untrusted endpoint. ]]>
