T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/video_api.py:29
- Finding
- Unrestricted API Base URL Override Can Disclose Credentials and Video Prompts<![CDATA[ ## Vulnerability Details **File Location**: `scripts/video_api.py`, lines 29–81 **Vulnerability Type**: Unvalidated authenticated endpoint configuration **Risk Level**: Medium ### Vulnerable Code ```python class SenseAudioVideoClient: def __init__(self) -> None: self.base_url = os.environ.get("SENSEAUDIO_BASE_URL", DEFAULT_BASE_URL).rstrip("/") self.api_key = os.environ.get("SENSEAUDIO_API_KEY", "").strip() self.model = DEFAULT_MODEL if not self.api_key: raise RuntimeError("Missing configuration: SENSEAUDIO_API_KEY") def _headers(self) -> Dict[str, str]: return { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", } def create_video(self, request: VideoRequest) -> str: prompt = (request.final_video_prompt or "").strip() if not prompt: raise RuntimeError("final_video_prompt must not be empty") payload = { "model": self.model, "content": [{"type": "text", "text": prompt}], "duration": DEFAULT_DURATION, "resolution": DEFAULT_RESOLUTION, "ratio": request.ratio, "provider_specific": {"generate_audio": True}, } resp = requests.post( f"{self.base_url}/v1/video/create", headers=self._headers(), json=payload, timeout=60, ) ``` The same unrestricted base URL is also used for status requests: ```python resp = requests.get( f"{self.base_url}/v1/video/status", headers=self._headers(), params={"id": clean_task_id}, timeout=30, ) ``` ### Technical Analysis The `SENSEAUDIO_BASE_URL` environment variable is accepted without validating its scheme, hostname, port, or destination. The client subsequently sends the `SENSEAUDIO_API_KEY` as a bearer token to that endpoint. Video-creation requests also transmit the complete finalized video prompt. Con ...[truncated 2053 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Enforce HTTPS for all provider endpoints: - Parse the configured URL with `urllib.parse.urlparse`. - Reject every scheme other than `https`. - Reject URLs containing user-information, fragments, or unexpected query parameters. 2. Allowlist trusted provider hostnames: - Permit `api.senseaudio.cn` by default. - If alternative provider hosts are required, maintain an explicit administrator-controlled allowlist. - Validate the normalized hostname rather than using suffix or substring matching. 3. Restrict destination ports to `443` unless a separately reviewed deployment explicitly requires another port. 4. Reject loopback, link-local, private, multicast, and reserved IP destinations where custom hosts are supported. Resolve hostnames and apply destination checks to reduce private-network request risks. 5. Do not send production credentials to arbitrary custom endpoints. Use separate scoped credentials for test or self-hosted environments. 6. Apply least privilege and credential rotation: - Scope the API key to only the video operations required by this skill. - Configure provider-side quota and usage limits. - Rotate the key immediately if an untrusted base URL may have been used. 7. Add automated tests confirming rejection of: - Plaintext HTTP URLs. - Unapproved external hosts. - Loopback and private-network destinations. - URLs containing embedded credentials or unexpected ports. ]]>
