T09 · Insecure Skill Coding Practices
- Location
recognize_road_user.py:240- Finding
Unrestricted API Endpoint Can Receive Sensitive Images and API Credentials
- Content
View full analysis
Vulnerability Details
File Location:
recognize_road_user.py:240-252,recognize_road_user.py:278-292
Vulnerability Type: Unvalidated network destination and unsafe credential forwarding
Risk Level: MediumVulnerable Code
python image_bytes = image_path.read_bytes() body, content_type = build_multipart_body( fields, {file_field: (image_path.name, image_bytes, None)}, ) request_url = build_request_url(api_url, api_key, api_key_mode, api_key_name) headers = {"Content-Type": content_type, "Content-Length": str(len(body))} if api_key_mode == "header" and api_key: headers[api_key_name] = api_key elif api_key_mode == "bearer" and api_key: headers["Authorization"] = f"Bearer {api_key}"python parser.add_argument("image", nargs="?", help="Path to the local image file") parser.add_argument("--api-url", default=os.getenv("TRAFFICEYE_API_URL", DEFAULT_API_URL)) parser.add_argument("--api-key", default=os.getenv("TRAFFICEYE_API_KEY")) parser.add_argument( "--api-key-mode", default=os.getenv("TRAFFICEYE_API_KEY_MODE", DEFAULT_API_KEY_MODE), choices=("header", "bearer", "form", "query"), ) parser.add_argument("--api-key-name", default=os.getenv("TRAFFICEYE_API_KEY_NAME", DEFAULT_API_KEY_NAME)) parser.add_argument("--file-field", default=os.getenv("TRAFFICEYE_FILE_FIELD", DEFAULT_FILE_FIELD)) parser.add_argument("--request-field", default=os.getenv("TRAFFICEYE_REQUEST_FIELD", DEFAULT_REQUEST_FIELD)) parser.add_argument("--request-json", default=os.getenv("TRAFFICEYE_REQUEST_JSON", DEFAULT_REQUEST_JSON)) parser.add_argument("--timeout", type=float, default=float(os.getenv("TRAFFICEYE_TIMEOUT_S", str(DEFAULT_TIMEOUT_S)))) parser.add_argument("--format", choices=("text", "json"), default="text") parser.add_argument("--response-json-file", help="Read a saved API response instead of calling the API")Technical Analysis
The Skill must uploa ...[truncated 2850 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse the configured endpoint before building or sending the request.
- Require the
httpsscheme for every request carrying an image or credential. - Reject URLs containing embedded user information or otherwise ambiguous authority components.
- Allowlist the expected TrafficEye hostname, such as
trafficeye.ai, for the default credential. - If custom deployments are required, maintain an explicit administrator-configured host allowlist rather than accepting arbitrary destinations.
- Require explicit user confirmation before transmitting an image to a non-default host.
- Never forward the TrafficEye credential to a custom host unless that host has been explicitly trusted for that credential.
- Disable query-string authentication by default and preferably remove it, because URLs are commonly retained in logs and telemetry.
- Reject all credential-bearing requests over plaintext HTTP.
- Document that images and license-plate information leave the local system before invoking the live API.
- Consider implementing separate credential configuration per approved endpoint to prevent accidental cross-service credential disclosure.
- Add automated tests confirming that HTTP URLs, unapproved hosts, malformed URLs, and credential forwarding to custom hosts are rejected.
