T09 · Insecure Skill Coding Practices
- Location
scripts/device_status.py:26- Finding
Unrestricted API Endpoint Allows Redirection of Device Tokens and Authentication Metadata
- Content
View full analysis
Vulnerability Details
File Location:
scripts/device_status.py, lines 26–27 and 49–57
Vulnerability Type: Unvalidated destination for sensitive outbound requests
Risk Level: HighVulnerable Code
python # API base address (switchable through an environment variable) JF_ENDPOINT = os.getenv("JF_ENDPOINT", "api-cn.jftechws.com") JF_BASE_URL = f"https://{JF_ENDPOINT}/gwp/v3"python url = f"{JF_BASE_URL}/rtc/device/status" headers = get_headers(uuid, app_key, app_secret, move_card) body = { "deviceTokenList": device_tokens, "region": region } response = requests.post(url, headers=headers, json=body, timeout=30)Technical Analysis
The destination hostname is read directly from the
JF_ENDPOINTenvironment variable and interpolated into the request URL without validation or an allowlist. Consequently, the request can be redirected to any HTTPS server rather than being restricted to the four regional API domains documented by the Skill.Each redirected request contains sensitive information:
- Device access tokens in
deviceTokenList - The platform account UUID
- The application key
- A timestamp
- A signature derived from the application secret
- A request identifier
The application secret itself is not transmitted directly. Nevertheless, device tokens and account authentication metadata are disclosed to the selected destination. The documentation states that device tokens remain valid for 24 hours.
Allowing arbitrary destinations exceeds the minimum privileges required for device-status queries. The declared functionality only needs access to the documented JFTech regional API hosts:
api-cn.jftechws.comapi-as.jftechws.comapi-eu.jftechws.comapi-na.jftechws.com
TLS does not mitigate this issue because the program intentionally establishes TLS with the attacker-selected hostname. A valid certificate for that hostname is suffi ...[truncated 1750 chars]
- Device access tokens in
- Remediation
View remediation
Remediation Suggestions
-
Replace the free-form hostname with a fixed region-to-endpoint mapping:
python ENDPOINTS = { "CN": "api-cn.jftechws.com", "AS": "api-as.jftechws.com", "EU": "api-eu.jftechws.com", "NA": "api-na.jftechws.com", } selected_region = os.getenv("JF_REGION", "CN") if selected_region not in ENDPOINTS: raise ValueError("Unsupported API region") JF_BASE_URL = f"https://{ENDPOINTS[selected_region]}/gwp/v3" -
If backward compatibility requires
JF_ENDPOINT, validate it against an exact hostname allowlist before constructing the URL:python ALLOWED_ENDPOINTS = { "api-cn.jftechws.com", "api-as.jftechws.com", "api-eu.jftechws.com", "api-na.jftechws.com", } endpoint = os.getenv("JF_ENDPOINT", "api-cn.jftechws.com") if endpoint not in ALLOWED_ENDPOINTS: raise ValueError("JF_ENDPOINT is not an approved API endpoint") -
Reject endpoint values containing schemes, user information, ports, paths, query strings, fragments, trailing dots, wildcard subdomains, or IP literals. Exact string matching against canonical hostnames is preferable.
-
Keep TLS certificate verification enabled and do not add an option that disables verification.
-
Minimize token exposure by sending only tokens needed for the requested operation and clearing unnecessary in-memory collections after batch processing where practical.
-
Treat endpoint configuration as security-sensitive. Prevent untrusted users, workflow inputs, or generated configuration from controlling the Skill's process environment.
-
Rotate potentially exposed device tokens and application credentials if the Skill has previously run with an untrusted
JF_ENDPOINT.
-
