T09 · Insecure Skill Coding Practices
- Location
scripts/bilibili-player.py:33- Finding
Unvalidated Page-Controlled URL Passed to the macOS open Command
- Content
View full analysis
Vulnerability Details
File Location:
scripts/bilibili-player.py, lines 33-41
Vulnerability Type: Insufficient URL validation before invoking an external protocol handler
Risk Level: MediumVulnerable Code
python href = element.get_attribute("href") if href and "/video/" in href: video_url = f"https:{href}" if href.startswith("//") else href print(f"✅ 找到视频:{video_url}") break if video_url: # 用 open 在当前浏览器打开 subprocess.run(["open", video_url])Technical Analysis
The script treats any page-provided
hrefcontaining the substring/video/as a trusted video URL. It does not parse the URL or enforce an allowlist for its scheme, hostname, port, or user-information component.Consequently, values such as
https://attacker.example/video/...or a registered custom protocol containing/video/can pass validation and be supplied to macOSopen. Theopenutility dispatches its argument to the application registered for the corresponding URL scheme.This is not shell command injection because
subprocess.runreceives an argument array and does not invoke a shell. The vulnerability instead concerns unsafe delegation of untrusted URLs to local protocol handlers.Attack Path
- An attacker influences the Bilibili search response, a loaded third-party page resource, or the network/browser environment.
- The resulting document contains an early matching anchor whose
hrefincludes/video/but points to an attacker-controlled domain or unexpected URL scheme. page.query_selector()selects that anchor.- The substring check accepts the malicious value without verifying that it is an HTTPS Bilibili URL.
- The script passes the value to macOS
open. - The operating system opens the attacker-controlled website or invokes the application associated with the supplied scheme.
Impact Assessment
Exploitation can cause an attacker-controlled websi ...[truncated 521 chars]
- Remediation
View remediation
Remediation Suggestions
Parse and validate the URL before invoking
open:- Resolve relative and protocol-relative links against an explicitly trusted Bilibili base URL using
urllib.parse.urljoin. - Parse the resolved result with
urllib.parse.urlparse. - Permit only the
httpsscheme. - Require the normalized hostname to be exactly
bilibili.comor a deliberately approved subdomain ending in.bilibili.com. - Reject URLs containing embedded credentials, unexpected ports, control characters, or unsupported schemes.
- Verify that the normalized path has the expected Bilibili video format rather than relying on a substring check.
- Use
subprocess.run(..., check=True)and handle failures explicitly.
Example validation approach:
python from urllib.parse import urljoin, urlparse resolved = urljoin("https://www.bilibili.com/", href) parsed = urlparse(resolved) hostname = (parsed.hostname or "").lower() trusted_host = ( hostname == "bilibili.com" or hostname.endswith(".bilibili.com") ) if ( parsed.scheme == "https" and trusted_host and parsed.username is None and parsed.password is None and parsed.port in (None, 443) and parsed.path.startswith("/video/") ): subprocess.run(["open", resolved], check=True) else: raise ValueError("Rejected untrusted video URL")- Resolve relative and protocol-relative links against an explicitly trusted Bilibili base URL using
