Back to skill

Security audit

Bilibili Video Summary

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to summarize Bilibili videos as described, but its URL handling and local tool execution are broader than the Bilibili-only purpose requires.

Install only if you are comfortable with a skill that makes outbound requests, invokes yt-dlp and whisper.cpp, and saves transcripts/comments locally. Use explicit Bilibili URLs, run it in a constrained environment with outbound access limited to Bilibili/media hosts, keep the output directory private, and pin or review dependency versions before automated use.

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
bili-transcript.py:108
Finding

Unrestricted URL Processing Enables Server-Side Request Forgery

Content
View full analysis
tuple: """Extract aid and cid from a Bilibili video URL""" try: html = http_get(url, timeout=10).decode("utf-8") 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") cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP), "--dump-json", "--no-download", url] result = subprocess.run(cmd, capture_output=True, text=True) ``` ```python def fetch_danmaku(url: str, output_dir: Path) -> str: """Download danmaku subtitles via yt-dlp, returns xml file path""" output_template = str(output_dir / "danmaku") cmd = [ *([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP), "--write-subs", "--sub-langs", "danmaku", "--skip-download", "-o", output_template, url, ] result = subprocess.run(cmd, capture_output=True, text=True) ``` ```python def download_audio(url: str, output_dir: str) -> str: """Download audio as m4a via yt-dlp""" output_path = Path(output_dir) / "audio.m4a" cmd = [ *([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP), "-f", "bestaudio[ext=m4a]/bestaudio", "-o", str(output_path), url, ] result = subprocess.run(cmd, capture_output=True, text=True) ``` ### Technical Analysis The command-line interface describes its input as a Bilibili video URL, but the implementation does not enforce that restriction. The supplied value is passed directly to `urllib.req ...[truncated 2769 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Open-Ended Third-Party Dependency Versions Permit Unreviewed Updates

Content
View full analysis
=2024.0 av>=10.0.0 ``` The associated installation guidance in `README.md:26` also instructs users to install dependencies without a lockfile or integrity hashes: ```bash pip install yt-dlp av ``` ### Technical Analysis Both dependencies use minimum-version constraints without upper bounds or exact pins. A fresh installation can therefore resolve to any later version available from the configured package index. The project does not include a lockfile or package hashes that identify the versions reviewed by the project author. This is not evidence that either named package is currently malicious. The risk is that installation behavior is non-reproducible and can automatically incorporate a future compromised, malicious, or incompatible release without a project-level security review. Because these packages are imported or executed as part of media processing, dependency code runs with the same filesystem and network privileges as the Skill. ### Attack Path 1. A user or Agent follows the documented installation instructions. 2. The Python package resolver selects the newest releases satisfying the open-ended constraints. 3. A future compromised or otherwise unsafe release is downloaded because no reviewed version or hash is enforced. 4. Installation-time or runtime package code executes with the privileges of the Skill process. 5. That code could access files available to the process, perform network operations, or alter generated output. This path depends on compromise or unsafe modification of an upstream package or distribution channel; no such compromise was identified during this audit. ### Impact Assessment If an accepted dependency release were compromised, its code would inherit the Skill process's privileges, potentially i ...[truncated 448 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (20)

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger list includes broad phrases such as 'video content', 'video summary', and 'bilibili video', which could cause the skill to activate on ordinary conversation rather than a clear user request to run it. Because activation leads to network fetching, local file creation, and possible shell execution for transcription, accidental invocation can cause privacy, cost, and safety issues.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill invokes shell commands, performs network access, reads environment variables, and writes files, but it does not declare any explicit tool scope or permission boundaries. This increases the chance an agent will run the skill with broader capabilities than necessary, making unintended downloads, file writes, or command execution harder to govern and audit.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill states that outputs are saved under './bili-output/' but does not prominently warn users up front that it downloads remote content and persists transcripts, comments, and metadata to local files. This can expose sensitive viewing interests or copyrighted/regulated content in local storage unexpectedly, especially in shared or automated environments.

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 · bili-transcript.py (reported line 114)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

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 · bili-transcript.py (reported line 128)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

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 · bili-transcript.py (reported line 190)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

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 · bili-transcript.py (reported line 321)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

Tainted flow: 'cmd' from os.environ.get (line 366, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · bili-transcript.py (reported line 114)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

Tainted flow: 'cmd' from os.environ.get (line 366, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · bili-transcript.py (reported line 128)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

Tainted flow: 'cmd' from os.environ.get (line 366, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · bili-transcript.py (reported line 190)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

Tainted flow: 'cmd' from os.environ.get (line 366, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · bili-transcript.py (reported line 321)May include surrounding context.

python
cmd = [*([YT_DLP] if isinstance(YT_DLP, str) else YT_DLP),
               "--dump-json", "--no-download", url]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info = json.loads(result.stdout)
            return info.get("aid"), info.get("cid")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · bili-transcript.py (reported line 148)May include surrounding context.

python
"""Get subtitle URL from Bilibili API"""
    try:
        data = http_get_json(
            f"https://api.bilibili.com/x/player/wbi/v2?aid={aid}&cid={cid}"
        )
        subtitles = data.get("data", {}).get("subtitle", {}).get("subtitles", [])
        if subtitles:

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · bili-transcript.py (reported line 245)May include surrounding context.

python
"""Get subtitle URL from Bilibili API"""
    try:
        data = http_get_json(
            f"https://api.bilibili.com/x/player/wbi/v2?aid={aid}&cid={cid}"
        )
        subtitles = data.get("data", {}).get("subtitle", {}).get("subtitles", [])
        if subtitles:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The whisper.cpp invocation forces the language to "zh" via the -l flag, which imposes a specific language/locale behavior regardless of user preference. This matches the policy-violation category because the file does not offer a language choice or explain that the tool is intentionally limited to Chinese-only use.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
83% confidence
Finding

This call executes a binary path derived from environment variables and optionally CLI input (WHISPER_CPP_DIR / WHISPER_MODEL_PATH), so a caller controlling the execution environment can redirect the tool to run an arbitrary local executable. In an agent or multi-tenant automation context, that turns this feature into a local code-execution primitive rather than a pure transcription step.

Content

Scanner excerpt · bili-transcript.py (reported line 377)May include surrounding context.

python
print(f"🎤 Transcribing with whisper.cpp...", file=sys.stderr)

    result = subprocess.run(cmd, capture_output=True, text=False)

    txt_output = str(Path(wav_path).with_suffix(".wav.txt"))

Tainted flow: 'cmd' from os.environ.get (line 366, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

This is a real tainted-flow issue: the executable path comes from WHISPER_CPP_DIR/CLI overrides and is passed directly to subprocess.run. In environments where skill users or upstream agents can influence environment variables or CLI arguments, an attacker can cause arbitrary local binaries to be executed with the skill's privileges.

Content

Scanner excerpt · bili-transcript.py (reported line 377)May include surrounding context.

python
print(f"🎤 Transcribing with whisper.cpp...", file=sys.stderr)

    result = subprocess.run(cmd, capture_output=True, text=False)

    txt_output = str(Path(wav_path).with_suffix(".wav.txt"))

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file explains that transcript text, danmaku, and comments are saved into local output files, but it does not include any caution about privacy or retention of scraped user-generated content. Because the skill handles external content and writes it to disk, a brief disclosure would improve user awareness of data handling.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency specification yt-dlp>=2024.0 is not pinned to an exact version, so installs may resolve to different releases over time, including versions with newly introduced breaking changes or security issues. In a skill that processes untrusted remote media from Bilibili, yt-dlp is a high-risk dependency because it handles network content and extractor logic, so supply-chain drift increases exposure.

Content

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

text
yt-dlp>=2024.0
av>=10.0.0

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
94% confidence
Finding

yt-dlp has multiple known advisories, and because the manifest does not pin a specific version, there is no way to verify whether the deployed version includes fixes. Given this skill fetches and extracts content from external video sources, any vulnerable yt-dlp release could expose the agent environment to command injection, malicious extractor behavior, or other parser/network-related attacks depending on the installed version and runtime platform.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The dependency av>=10.0.0 is also unpinned, which makes builds non-reproducible and can silently introduce vulnerable or incompatible releases. This is especially relevant because av parses complex multimedia data, an attack surface historically associated with memory-safety and media parsing flaws in underlying codec stacks.

Content

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

text
yt-dlp>=2024.0
av>=10.0.0

Static analysis

No suspicious patterns detected.