Back to skill

Security audit

Bilibili Player

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward Bilibili search-and-open helper, with some ordinary browser-opening and dependency risks users should understand.

Install this only if you are comfortable with a skill opening Bilibili results in your default browser, potentially using your existing Bilibili login session. Prefer reviewing or hardening the URL validation so only HTTPS bilibili.com or approved Bilibili subdomains can be opened, and install Playwright in an isolated environment with pinned versions if reproducibility matters.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
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: Medium

Vulnerable 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 href containing 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 macOS open. The open utility dispatches its argument to the application registered for the corresponding URL scheme.

This is not shell command injection because subprocess.run receives an argument array and does not invoke a shell. The vulnerability instead concerns unsafe delegation of untrusted URLs to local protocol handlers.

Attack Path

  1. An attacker influences the Bilibili search response, a loaded third-party page resource, or the network/browser environment.
  2. The resulting document contains an early matching anchor whose href includes /video/ but points to an attacker-controlled domain or unexpected URL scheme.
  3. page.query_selector() selects that anchor.
  4. The substring check accepts the malicious value without verifying that it is an HTTPS Bilibili URL.
  5. The script passes the value to macOS open.
  6. 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:

  1. Resolve relative and protocol-relative links against an explicitly trusted Bilibili base URL using urllib.parse.urljoin.
  2. Parse the resolved result with urllib.parse.urlparse.
  3. Permit only the https scheme.
  4. Require the normalized hostname to be exactly bilibili.com or a deliberately approved subdomain ending in .bilibili.com.
  5. Reject URLs containing embedded credentials, unexpected ports, control characters, or unsupported schemes.
  6. Verify that the normalized path has the expected Bilibili video format rather than relying on a substring check.
  7. 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")

T08 · Insecure Dependencies

Note
Location
SKILL.md:67
Finding

Unpinned Third-Party Playwright Installation Instruction

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 67-70
Vulnerability Type: Mutable and unverifiable third-party dependency installation
Risk Level: Low

Vulnerable Code

markdown
**Dependencies:**
- Python 3
- Playwright (`pip3 install playwright`)

Technical Analysis

The documented installation command installs the latest Playwright release and its transitive dependencies from the user's configured Python package index. It does not specify a reviewed version, verify package hashes, use a lock file, or identify a trusted package index.

Package resolution can therefore change over time without any change to the audited Skill. A compromised package release, dependency, package index, or dependency-resolution configuration could introduce code that was not part of this audit.

The package name itself is correctly spelled, and the audited project does not automatically execute this installation command. The risk arises when a user follows the documented setup instruction.

Attack Path

  1. A user follows the dependency setup documentation and runs pip3 install playwright.
  2. pip resolves the current package and dependency versions through the user's configured package index.
  3. A compromised release, transitive dependency, index, or package-resolution source supplies malicious package content.
  4. Package installation or later import executes attacker-controlled code with the privileges of the installing or running user.

Impact Assessment

A compromised Python dependency can execute arbitrary code as the user running pip or the Skill. Potential consequences include access to user-readable files, modification of user-owned data, use of network credentials available to the process, and execution of additional commands.

No malicious dependency is present in the audited files, and exploitation requires compromise or manipulation of the external dependency supply chain. The proj ...[truncated 180 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin Playwright to a specifically reviewed version instead of installing an unconstrained latest release.
  2. Provide a lock file that pins all transitive dependencies.
  3. Record and verify package hashes with pip install --require-hashes.
  4. Document the trusted Python package index explicitly and require TLS.
  5. Install dependencies in an isolated virtual environment with ordinary user privileges.
  6. Establish a process for reviewing and deliberately updating pinned dependencies.
  7. Pin and document the corresponding Playwright browser binary version where reproducible deployment is required.

A hardened installation workflow could use a reviewed requirements file:

text
playwright==REVIEWED_VERSION --hash=sha256:REVIEWED_PACKAGE_HASH

Install it with:

bash
python3 -m venv .venv
.venv/bin/python -m pip install \
  --require-hashes \
  --index-url https://pypi.org/simple \
  -r requirements.txt
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill describes shell-capable behavior (open, shell wrapper scripts) but does not declare any explicit tool scope or permissions. This weakens enforcement and review boundaries, making it easier for an agent to invoke shell functionality without clear user- or platform-level constraints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The description does not clearly warn users that the skill will open their browser and may operate within an already authenticated Bilibili session using existing cookies. That omission undermines informed consent and can expose users to privacy or account-context risks when external content is opened automatically.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The trigger text is broad enough to match many generic media-related requests, increasing the chance the skill is invoked unexpectedly. Because the skill performs side effects by opening the user's browser, overbroad matching can cause surprising actions and reduce meaningful user consent.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/bilibili-player.py (reported line 41)May include surrounding context.

python
if video_url:
            # 用 open 在当前浏览器打开
            subprocess.run(["open", video_url])
            print("🎬 已在浏览器中打开!")
        else:
            # 没找到视频,打开搜索页面

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/bilibili-player.py (reported line 46)May include surrounding context.

python
else:
            # 没找到视频,打开搜索页面
            print("❌ 没找到视频,打开搜索页面")
            subprocess.run(["open", search_url])
        
        browser.close()

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest and usage guidance are primarily in Chinese and all examples assume Chinese-language interaction, but the file does not say that the skill is intentionally limited to Chinese-speaking users or offer an alternative language option. Under the policy, forcing a specific language without opt-in can be a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's natural-language comments and user-facing usage strings are entirely in Chinese, which imposes a specific language on users without offering an alternative or opt-in. This matches the language/locale policy violation category because no choice or justification is provided in the file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.