T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/transcribe_with_fallback.py:238- Finding
Unrestricted Caption URL Fetch Enables SSRF and Local File Disclosure
- Content
View full analysis
tuple[str, str]: for track in record.get("caption_urls", []): if not isinstance(track, dict): continue url = str(track.get("url") or "").strip() ext = str(track.get("ext") or "").strip() if not url or not ext: continue try: def read_payload() -> str: with urllib.request.urlopen(url, timeout=timeout_seconds) as response: return response.read().decode("utf-8", errors="ignore") payload = with_retries( read_payload, retries=retries, delay_seconds=delay_seconds, ) except Exception as exc: # noqa: BLE001 continue text = caption_payload_to_text(ext, payload) if text: label = track.get("category") or "caption" return text, f"{label}-url:{ext}" ``` ### Technical Analysis The script accepts `caption_urls` from the input dataset and passes each URL directly to `urllib.request.urlopen`. It does not validate: - The URL scheme. - Whether the destination belongs to YouTube or an expected Google caption service. - Whether the resolved address is private, loopback, link-local, or otherwise internal. - Whether redirects remain within an approved destination set. Because `urllib` supports schemes other than HTTPS, a crafted input can cause the process to retrieve internal HTTP resources or read local files through a `file://` URL. Retrieved content is treated as transcript text and subsequently written into transcript and JSON report artifacts. This network behavior exceeds the minimum p ...[truncated 1347 chars]- Remediation
View remediation
