T09 · Insecure Skill Coding Practices
- Location
scripts/transcribe_audio.py:221- Finding
Unvalidated Transcription Result URL Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/transcribe_audio.py:221-223andscripts/transcribe_audio.py:336-339
Vulnerability Type: Server-Side Request Forgery through an untrusted API response URL
Risk Level: MediumVulnerable code:
python def _fetch_json_url(url: str) -> dict[str, Any]: try: with urllib.request.urlopen(url, timeout=180) as resp: raw = resp.read().decode("utf-8") except urllib.error.HTTPError as exc: detail = exc.read().decode("utf-8", errors="ignore") raise RuntimeError(f"Transcription URL HTTP {exc.code}: {detail}") from exc except urllib.error.URLError as exc: raise RuntimeError(f"Transcription URL request failed: {exc}") from exc try: return json.loads(raw) except json.JSONDecodeError as exc: raise RuntimeError(f"Invalid transcription JSON: {raw[:500]}") from excpython if async_mode and status.upper() == "SUCCEEDED": transcription_url = (((final_resp.get("output") or {}).get("result") or {}).get("transcription_url") or "") if isinstance(transcription_url, str) and transcription_url: transcription_json = _fetch_json_url(transcription_url) final_resp["transcription_result"] = transcription_jsonTechnical Analysis
The asynchronous task response supplies
transcription_url, which is passed directly tourllib.request.urlopen. The implementation does not constrain the URL scheme or destination, validate the resolved IP address, restrict redirects, or allowlist expected Alibaba Cloud result-storage domains.Consequently, any party capable of influencing the task response—such as a compromised upstream service, intercepted response path, or malicious proxy—could direct the process to make a request to an attacker-selected destination. Potential destinations include loopback interfaces, private network services, link-local cloud metadat ...[truncated 2441 chars]
- Remediation
View remediation
Remediation Suggestions
- Require
httpsand reject URLs containing user information, unexpected ports, fragments, or malformed hostnames. - Allowlist the exact Alibaba Cloud or OSS domains documented for transcription-result delivery. Use strict hostname-boundary comparisons rather than substring matching.
- Resolve the hostname and reject every address in loopback, private, link-local, multicast, unspecified, reserved, and other non-public ranges for both IPv4 and IPv6.
- Disable automatic redirects or validate the scheme, hostname, port, and resolved addresses at every redirect hop.
- Mitigate DNS rebinding by connecting only to a validated resolved address while preserving correct TLS hostname verification.
- Set a substantially shorter connection/read timeout and enforce a maximum response size before parsing JSON.
- Validate the response content type and expected transcription-result schema.
- Prefer authenticated result retrieval through a fixed provider API when available rather than following a URL supplied in response data.
- Store output files with restrictive permissions when transcripts may contain sensitive speech or internal response data.
- Require
