T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/bili-summary.py:34
- Finding
- Unrestricted URL Processing Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bili-summary.py`, lines 34-48; additional affected call sites at lines 100-101, 143-149, 260-266, and 276 **Vulnerability Type**: Server-Side Request Forgery through unrestricted user-supplied URLs **Risk Level**: High ### Vulnerable Code ```python def get_aid_cid(url: str) -> tuple: """从视频URL获取aid和cid""" try: req = urllib.request.Request(url, headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }) with urllib.request.urlopen(req, timeout=10) as response: html = response.read().decode('utf-8') # 提取 __INITIAL_STATE__ match = re.search(r'window\.__INITIAL_STATE__=(.*?);\(function', html) if match: data = json.loads(match.group(1)) video_data = data.get("videoData", {}) return video_data.get("aid"), video_data.get("cid") # 备用方法:使用 yt-dlp cmd = [YT_DLP, "--dump-json", "--no-download", url] result = subprocess.run(cmd, capture_output=True, text=True) ``` The unrestricted argument is also passed to other network-capable operations: ```python def get_video_info(url: str) -> dict: """获取视频信息""" cmd = [YT_DLP, "--dump-json", "--no-download", url] result = subprocess.run(cmd, capture_output=True, text=True) ``` ```python parser.add_argument("url", help="B站视频URL") ``` ### Technical Analysis The positional argument is described as a Bilibili URL, but the implementation does not enforce that restriction. It performs no validation of: - The URL scheme - The destination hostname - Explicit ports or embedded credentials - The resolved IP address - Redirect destinations - Whether the destination is a loopback, private, link-local, or reserved address `urllib.request.urlopen()` directly opens the supplied URL and may follow redirects. The same value is also passed to the general-purpose `yt-dlp` executable, which supports mor ...[truncated 1823 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Accept only `https` URLs. 2. Apply an explicit hostname allowlist for the Bilibili domains required by the feature. 3. Reject URLs containing user information, fragments, nonstandard ports, or malformed hostnames. 4. Resolve the destination before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses. 5. Disable redirects or validate the scheme, hostname, port, and resolved address of every redirect target. 6. Revalidate immediately before each network operation to reduce DNS rebinding exposure. 7. Apply the same validation before passing a URL to `yt-dlp`; validating only the direct `urllib` request is insufficient. 8. Where possible, convert accepted Bilibili identifiers into application-constructed API URLs instead of opening arbitrary user-provided URLs. 9. Add request-size, download-size, duration, and redirect-count limits. 10. Return clear validation errors rather than silently falling back to another network-capable operation. ]]>
