T09 · Insecure Skill Coding Practices
- Location
scripts/video_generate.py:11- Finding
Bearer API credentials can be transmitted to an attacker-controlled API endpoint
- Content
View full analysis
Vulnerability Details
File Location:
scripts/video_generate.py, lines 11-21; credential use occurs in_get_headers,_create_video_task, and_get_task_status
Vulnerability Type: Unrestricted externally configurable service endpoint with automatic credential forwarding
Risk Level: HighRelevant Code:
python API_KEY = ( os.getenv("ARK_API_KEY") or os.getenv("MODEL_VIDEO_API_KEY") or os.getenv("MODEL_AGENT_API_KEY") ) API_BASE = ( os.getenv("ARK_BASE_URL") or os.getenv("MODEL_VIDEO_API_BASE") or "https://ark.cn-beijing.volces.com/api/v3" ).rstrip("/") API_BASE = API_BASE.replace("/api/coding/v3", "/api/v3")The configured credential is unconditionally placed in an authorization header:
python def _get_headers() -> dict: return { "Content-Type": "application/json", "Authorization": f"Bearer {API_KEY}", }The header is then sent to the configurable endpoint:
python async def _create_video_task( prompt: str, config: VideoGenerationConfig, model_name: str ) -> dict: url = f"{API_BASE}/contents/generations/tasks" body = _build_request_body(prompt, config, model_name) async with httpx.AsyncClient(timeout=60.0) as client: response = await client.post(url, headers=_get_headers(), json=body) response.raise_for_status() return response.json()python async def _get_task_status(task_id: str) -> dict: url = f"{API_BASE}/contents/generations/tasks/{task_id}" async with httpx.AsyncClient(timeout=60.0) as client: response = await client.get(url, headers=_get_headers()) response.raise_for_status() return response.json()Technical Analysis
ARK_BASE_URLandMODEL_VIDEO_API_BASEare accepted without validating their scheme, hostname, port, or relationship to the expected Volcengine service. Regardless o ...[truncated 2228 chars]- Remediation
View remediation
Remediation Suggestions
- Allowlist the exact production API host or a narrowly defined set of approved hosts. Reject all other destinations before constructing headers.
- Require HTTPS and reject URLs containing user information, fragments, unexpected ports, IP literals, or ambiguous hostnames.
- Keep credential selection bound to the selected provider. Never forward an ARK credential to an arbitrary custom endpoint.
- If custom endpoints are operationally required, require a separate endpoint-specific credential and explicit administrator approval.
- Validate the final URL immediately before every request, including after normalization and redirects.
- Disable automatic HTTP redirects, or validate every redirect destination before forwarding the authorization header.
- Use a preconfigured
httpx.AsyncClientwith a fixed trusted base URL rather than concatenating an unrestricted environment value. - Redact authorization headers, prompts, and signed media URLs from logs and exception telemetry.
- Rotate any API key that may already have been used while the endpoint variables were controlled by an untrusted party.
- Add tests confirming that unapproved domains, non-HTTPS schemes, unexpected ports, and cross-origin redirects are rejected.
