T09 · Insecure Skill Coding Practices
- Location
scripts/get_transcript.py:17- Finding
Bypassable Hostname Allowlist Permits Requests to Attacker-Controlled Hosts
- Content
View full analysis
Vulnerability Details
File Location:
scripts/get_transcript.py, lines 17-25; unvalidated URL execution occurs at lines 98-115
Vulnerability Type: Improper hostname validation
Risk Level: MediumVulnerable Code
python def detect_platform(url: str) -> str: """Detect video platform from URL.""" domain = urlparse(url).netloc.lower() if any(d in domain for d in ['youtube.com', 'youtu.be', 'youtube-nocookie.com']): return 'youtube' elif any(d in domain for d in ['bilibili.com', 'b23.tv']): return 'bilibili' else: return 'unknown'The accepted URL is subsequently passed unchanged to
yt-dlp:python if platform == 'bilibili': cmd.extend([ "--add-header", "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "--add-header", "Referer: https://www.bilibili.com/", ]) cmd.append(url) try: result = subprocess.run(cmd, cwd=temp_dir, check=True, capture_output=True)Technical Analysis
detect_platform()checks whether an allowed domain string occurs anywhere inurlparse(url).netloc. This is substring matching rather than validation against an exact hostname or a legitimate subdomain boundary.Consequently, attacker-controlled hostnames such as
youtube.com.attacker.example,fakebilibili.com, orb23.tv.attacker.examplesatisfy the check. The URL is then passed directly toyt-dlp, causing the dependency to process and potentially contact a host outside the advertised YouTube and Bilibili trust boundary.Using an argument list with
subprocess.run()prevents conventional shell metacharacter injection in this code path. The vulnerability is instead an outbound destination-validation weakness. Redirect handling performed byyt-dlpmay also allow subsequent requests to destinations not ...[truncated 1193 chars]- Remediation
View remediation
Remediation Suggestions
Validate the parsed hostname using exact equality or a dot-delimited subdomain boundary:
python from urllib.parse import urlparse ALLOWED_HOSTS = { "youtube": ( "youtube.com", "www.youtube.com", "m.youtube.com", "youtu.be", "youtube-nocookie.com", "www.youtube-nocookie.com", ), "bilibili": ( "bilibili.com", "www.bilibili.com", "b23.tv", ), } def host_matches(host: str, allowed: str) -> bool: return host == allowed or host.endswith("." + allowed) def detect_platform(url: str) -> str: parsed = urlparse(url) host = (parsed.hostname or "").lower().rstrip(".") if parsed.scheme != "https": return "unknown" for platform, allowed_hosts in ALLOWED_HOSTS.items(): if any(host_matches(host, allowed) for allowed in allowed_hosts): return platform return "unknown"Additional hardening should include:
- Reject URLs containing credentials in the authority component.
- Permit only required schemes, preferably HTTPS.
- Define whether arbitrary subdomains are necessary; use exact hostnames where possible.
- Review and restrict redirect behavior. If redirects must be followed, validate every redirect destination against the same allowlist.
- Add tests for malicious suffix and prefix cases, including
youtube.com.example.org,notyoutube.com, andb23.tv.example.org. - Consider applying network-level egress restrictions as defense in depth.
