T09 · Insecure Skill Coding Practices
- Location
scripts/ptz_control.py:30- Finding
Unrestricted API Endpoint Allows Disclosure of Device Credentials and Authenticated Requests
- Content
View full analysis
Vulnerability Details
File Location:
scripts/ptz_control.py, lines 30–31, 39–48, and 59–86; the same request pattern is repeated at lines 108–132, 154–179, 202–229, 249–254, and 271–276.
Vulnerability Type: Unvalidated network destination for sensitive authenticated 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" 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 ptz_direction(device_token: str, uuid: str, app_key: str, app_secret: str, move_card: int, direction: str, command: str, channel: int = 0, step: int = 5) -> Dict[str, Any]: url = f"{JF_BASE_URL}/rtc/device/opdev/{device_token}" headers = get_headers(uuid, app_key, app_secret, move_card) direction_map = { "up": "DirectionUp", "down": "DirectionDown", "left": "DirectionLeft", "right": "DirectionRight", "leftup": "DirectionLeftUp", "leftdown": "DirectionLeftDown", "rightup": "DirectionRightUp", "rightdown": "DirectionRightDown" } body = { "Name": "OPPTZControl", "OPPTZControl": { "Command": direction_map.get(direction.lower(), direction), "Parameter": { ...[truncated 3295 chars]- Remediation
View remediation
Remediation Suggestions
-
Replace unrestricted endpoint configuration with an explicit allowlist containing only the documented service hosts:
api-cn.jftechws.comapi-as.jftechws.comapi-eu.jftechws.comapi-na.jftechws.com
-
Parse and validate endpoint configuration before creating any request. Reject:
- Unknown hostnames
- Embedded usernames or passwords
- URL paths or query strings
- Non-default ports
- IP-address literals
- Invalid or ambiguous hostname syntax
-
Prefer a region selector such as
CN,AS,EU, orNA, then map that value internally to a fixed trusted hostname. This avoids accepting a raw network destination. -
Keep TLS certificate verification enabled and consider certificate or public-key pinning if supported by the deployment environment.
-
If the upstream API supports it, transmit the device token in an authorization header rather than in the URL path. Ensure credentials and signed headers are redacted from application, proxy, and diagnostic logs.
-
Use short-lived, device-scoped tokens with only the PTZ permissions needed for the requested operation. Revoke and rotate any token suspected of having been sent to an untrusted endpoint.
-
Add automated tests confirming that unsupported hosts, ports, paths, credentials, and malformed endpoint values are rejected before any network request occurs.
-
