T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate_video.py:138
- Finding
- Provider-Controlled Video Polling URL Leaks the Provider Bearer Token## Vulnerability Details **File Location**: `scripts/generate_video.py`, lines 138–152 **Vulnerability Type**: Arbitrary authenticated outbound request / credential disclosure **Risk Level**: High ### Vulnerable Code ```python status_url = extract_status_url(payload) job_id = extract_job_id(payload) if not status_url and job_id: status_url = base_url + endpoint_template.format(id=job_id) if not status_url: return payload if status_url.startswith("/"): status_url = base_url + status_url headers = {"Authorization": f"Bearer {api_key}", "Accept": "application/json"} last_payload = payload for _ in range(max_polls): try: resp = requests.get(status_url, headers=headers, timeout=timeout) ``` ### Technical Analysis The asynchronous video workflow accepts a polling URL obtained from the provider response through `extract_status_url()`. Absolute URLs are used without validating their scheme, hostname, port, resolved IP address, or relationship to the configured provider origin. The request then unconditionally includes the configured provider API key in an `Authorization: Bearer` header. A malicious or compromised generation endpoint can return an attacker-controlled absolute `status_url`, `poll_url`, `result_url`, or `retrieve_url`. The polling routine will consequently send the provider credential to that destination. This behavior exceeds the minimum privileges required for asynchronous polling. Poll requests only need to reach the configured provider or an explicitly trusted polling origin; they do not need arbitrary Internet or internal-network access with provider credentials attached. ### Attack Path 1. An attacker controls, compromises, or impersonates the configured video-generation endpoint. 2. A user invokes `generate_video.py`, causing an authenticated generation request. 3. The endpoint returns a successful asynchronous payload containing an absolute URL such as an attacker ...[truncated 1211 chars]
- Remediation
- ## Remediation Suggestions 1. Resolve relative polling paths against the configured provider URL using a standards-compliant URL resolver such as `urllib.parse.urljoin`. 2. Permit polling only when the resulting URL has the same normalized scheme, hostname, and effective port as the configured provider. 3. Require HTTPS except where an explicit, narrowly scoped local-development option permits HTTP. 4. Never attach the provider `Authorization` header to a cross-origin polling request. 5. Reject URLs resolving to loopback, private, link-local, multicast, reserved, or unspecified IP ranges unless explicitly required by trusted local configuration. 6. Resolve and validate all returned addresses to mitigate DNS rebinding. 7. Disable redirects for authenticated polling, or manually validate every redirect target before following it. 8. Add tests covering attacker-controlled absolute polling URLs, cross-origin redirects, IPv4 and IPv6 loopback addresses, private ranges, and cloud metadata addresses.
