Back to skill

Security audit

Bilili-downloader

Security checks for vulnerabilities and agentic risk

Overview

The skill is a straightforward Bilibili downloader, but it does not enforce its claimed Bilibili-only scope before giving user input to yt-dlp.

Review before installing if the agent will run with broad network or filesystem access. Use only trusted Bilibili URLs, prefer a sandboxed download directory, and consider adding strict Bilibili host validation, a '--' separator before URLs, download size limits, and a pinned yt-dlp version.

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

Complete 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

  1. An attacker supplies a URL that does not point to an approved Bilibili host, potentially including a destination on an internal or loopback network.
  2. argparse assigns the value to args.url.
  3. The script copies it into url without validation.
  4. get_video_info, list_formats, and the applicable download function pass the URL to yt-dlp.
  5. yt-dlp attempts to contact and process the attacker-selected destination using the network access available to the Skill process.
  6. Response behavior, metadat ...[truncated 704 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the input with a standard URL parser before invoking yt-dlp.
  2. Require HTTPS and reject embedded credentials, unexpected ports, malformed hosts, fragments where unnecessary, and unsupported schemes.
  3. Apply an explicit, narrowly defined allowlist of required Bilibili hostnames. Compare normalized hostnames rather than using suffix or substring checks.
  4. Resolve the hostname and reject loopback, private, link-local, multicast, reserved, and unspecified IP ranges for both IPv4 and IPv6.
  5. Validate every redirect destination rather than validating only the initial URL.
  6. Run the downloader in a sandbox with restricted outbound networking and minimal filesystem permissions.
  7. Store downloads in a dedicated directory with controlled permissions and storage limits.
  8. Add tests covering non-Bilibili domains, deceptive hostname suffixes, IP literals, alternate ports, redirects, and private-network destinations.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded and Unverified Third-Party Dependency

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1
Vulnerability Type: Non-reproducible dependency resolution without integrity verification
Risk Level: Low

Complete Code Snippet

text
yt-dlp>=2023.01.01

Technical Analysis

The dependency specification defines only a minimum version. It has no exact version pin, upper bound, lock file, or package hash. Consequently, separate installations can resolve to different future releases that were not part of the reviewed project.

This does not establish that the named package or any current release is malicious. The weakness is that installation implicitly trusts any later version accepted by the package resolver and configured package index. Because the script executes the installed yt-dlp command for metadata retrieval and downloads, compromise of the dependency distribution path or an unsafe future release would directly affect runtime behavior.

Attack Path

  1. A deployment installs dependencies from requirements.txt.
  2. The package resolver selects any available yt-dlp release newer than or equal to the stated minimum.
  3. A newer compromised, unauthorized, or incompatible release is obtained from the configured package source.
  4. The Skill invokes the installed yt-dlp executable through subprocess.run.
  5. The dependency executes with the same network access, filesystem access, environment, and operating-system privileges as the Skill process.

This path requires compromise or unsafe modification of the dependency release, package repository, index configuration, or distribution channel; the current project does not itself demonstrate such a compromise.

Impact Assessment

A compromised dependency could act with the full privileges of the Skill process whenever yt-dlp is invoked. Potential scope includes reading or modifying process-accessible files, accessing available environment data, making outbound network reque ...[truncated 240 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin yt-dlp to an exact version that has been reviewed and tested.
  2. Generate a lock file containing cryptographic hashes and install with hash verification enabled.
  3. Retrieve packages only from an approved, authenticated package index or internal mirror.
  4. Update the pinned version through a controlled process that includes changelog review, vulnerability scanning, and regression testing.
  5. Record and verify the provenance of release artifacts where supported.
  6. Run yt-dlp with least privilege, restricted outbound networking, a sanitized environment, and access only to the designated download directory to reduce the impact of a compromised dependency.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (8)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs the agent to execute a local Python downloader script via shell, but the manifest does not declare any tool scope or allowed-tools restrictions. This creates an authorization gap where the agent may use shell access without explicit scoping, increasing the chance of unintended command execution or abuse if the URL or surrounding workflow is manipulated.

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/download_bilibili.py (reported line 24)May include surrounding context.

python
"--dump-json",
            url
        ]
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        return json.loads(result.stdout)
    except subprocess.CalledProcessError as e:
        print(f"获取视频信息失败: {e}")

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/download_bilibili.py (reported line 45)May include surrounding context.

python
"--dump-json",
            url
        ]
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        return json.loads(result.stdout)
    except subprocess.CalledProcessError as e:
        print(f"获取视频信息失败: {e}")

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/download_bilibili.py (reported line 76)May include surrounding context.

python
"--dump-json",
            url
        ]
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        return json.loads(result.stdout)
    except subprocess.CalledProcessError as e:
        print(f"获取视频信息失败: {e}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
80% confidence
Finding

Although the subprocess is invoked without a shell, it passes a user-controlled URL directly to yt-dlp without a protective '--' separator or domain validation. A crafted argument beginning with '-' could be interpreted by yt-dlp as an option rather than a URL, potentially altering downloader behavior, causing unintended file writes, extra network access, or other unsafe side effects in the agent environment.

Content

Scanner excerpt · scripts/download_bilibili.py (reported line 152)May include surrounding context.

python
])
        
        print(f"开始下载视频: {url}")
        result = subprocess.run(cmd, check=True)
        
        if result.returncode == 0:
            print("视频下载成功!")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
81% confidence
Finding

This playlist download path has the same option-injection issue: an attacker-controlled 'url' is appended directly to the yt-dlp argument list without '--' or strict validation. In a batch-download workflow the effect can be amplified, since altered yt-dlp options may trigger broader downloads, more disk usage, or unexpected output behavior across multiple items.

Content

Scanner excerpt · scripts/download_bilibili.py (reported line 184)May include surrounding context.

python
])
        
        print(f"开始下载播放列表: {url}")
        result = subprocess.run(cmd, check=True)
        
        if result.returncode == 0:
            print("播放列表下载成功!")

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified as yt-dlp>=2023.01.01, which allows installation of any newer release and makes builds non-reproducible. This creates supply-chain risk because future installs may pull in vulnerable, malicious, or behavior-changing versions without review; in a downloader skill that fetches untrusted remote content, that dependency is security-sensitive.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
yt-dlp>=2023.01.01

Unverifiable Dependency: yt-dlp has 16 known advisory(ies) (CVE-2023-46121 (yt-dlp Generic Extractor MITM Vulnerability via Arbitrary Proxy Injection); GHSA-3v33-3wmw-3785 (yt-dlp has dependency on potentially malicious third-party code in Douyu extract); CVE-2023-40581 ( yt-dlp on Windows vulnerable to `--exec` command injection when using `%q`) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

yt-dlp has multiple known security advisories, and because the manifest does not pin a specific version, it is impossible to determine whether installations will use an affected release. This is more concerning in this skill because yt-dlp processes attacker-controlled URLs and metadata from external sites, increasing exposure to parser, extractor, and command-execution flaws in the dependency.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.