T09 · Insecure Skill Coding Practices
- Location
scripts/download_bilibili.py:175- Finding
Unrestricted User-Supplied URL Passed to yt-dlp
- Content
View full analysis
Vulnerability Details
File Location:
scripts/download_bilibili.py:175-189
Vulnerability Type: Missing URL and destination validation
Risk Level: MediumComplete Code Snippet
python args = parser.parse_args() url = args.url format_choice = args.format_choice print("正在分析视频信息...") # 获取视频信息 info = get_video_info(url)The value reaches the subprocess invocation in
scripts/download_bilibili.py:16-22:python cmd = [ "yt-dlp", "--dump-json", url ] result = subprocess.run(cmd, capture_output=True, text=True, check=True)The same unvalidated URL is also used by the format-listing and download functions.
Technical Analysis
The Skill declares that it downloads Bilibili content, but it does not parse or validate the supplied URL's scheme, hostname, port, or resolved destination. The user-controlled value is passed directly to
yt-dlp, which supports sources beyond Bilibili and performs network requests on behalf of the process.Although subprocess arguments are safely supplied as a list and no direct shell-command injection is present, argument-array usage does not prevent server-side request forgery or out-of-scope network access. An attacker can provide a non-Bilibili URL or a URL resolving to a destination accessible from the host. Redirects and DNS resolution must also be considered when validating destinations.
Attack Path
- An attacker supplies a URL that does not point to an approved Bilibili host, potentially including a destination on an internal or loopback network.
argparseassigns the value toargs.url.- The script copies it into
urlwithout validation. get_video_info,list_formats, and the applicable download function pass the URL toyt-dlp.yt-dlpattempts to contact and process the attacker-selected destination using the network access available to the Skill process.- Response behavior, metadat ...[truncated 704 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse the input with a standard URL parser before invoking
yt-dlp. - Require HTTPS and reject embedded credentials, unexpected ports, malformed hosts, fragments where unnecessary, and unsupported schemes.
- Apply an explicit, narrowly defined allowlist of required Bilibili hostnames. Compare normalized hostnames rather than using suffix or substring checks.
- Resolve the hostname and reject loopback, private, link-local, multicast, reserved, and unspecified IP ranges for both IPv4 and IPv6.
- Validate every redirect destination rather than validating only the initial URL.
- Run the downloader in a sandbox with restricted outbound networking and minimal filesystem permissions.
- Store downloads in a dedicated directory with controlled permissions and storage limits.
- Add tests covering non-Bilibili domains, deceptive hostname suffixes, IP literals, alternate ports, redirects, and private-network destinations.
- Parse the input with a standard URL parser before invoking
