Back to skill

Security audit

bilibili-danmaku-extractor ​

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says: it fetches public Bilibili danmaku and saves JSON/Markdown files, with no hidden persistence or credential use found.

Install only if you are comfortable with the skill contacting Bilibili and writing extracted public comments to your selected output directory. Treat the generated Markdown as untrusted third-party content, especially before opening it in permissive renderers or feeding it to another AI agent. Prefer pinning dependencies for reproducible installs.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
main.py:142
Finding

Untrusted Bilibili Content Is Exported as Active Markdown

Content
View full analysis
**BV号**: `{video_info['bvid']}` ") lines.append(f"> **UP主**: {video_info['owner']} ") lines.append(f"> **弹幕总数**: {len(danmakus)} 条 ") lines.append(f"> **导出时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} ") lines.append("") lines.append("---") lines.append("") lines.append(f"**视频简介**: {video_info['desc'][:200]}{'...' if len(video_info['desc']) > 200 else ''}") lines.append("") lines.append("---") lines.append("") lines.append(f"## 全部弹幕 (共 {len(danmakus)} 条)") lines.append("") for i, d in enumerate(danmakus, 1): time_str = format_time(d['time']) text = d['text'].replace('\n', ' ') lines.append(f"`[{time_str}]` {text}") ``` ### Technical Analysis The video title, description, owner name, and danmaku text originate from an external service and can contain uploader- or user-controlled content. The exporter places these values directly into a Markdown document without escaping Markdown metacharacters or removing raw HTML. Replacing newline characters in danmaku does not neutralize inline Markdown, links, images, or HTML. Depending on the Markdown renderer, crafted content can therefore create deceptive links, external image requests, forged document sections, or active HTML elements. If the generated Markdown is subsequently supplied to an AI agent, attacker-authored text could also be interpreted as instructions. That represents a potential indirect prompt-injection path in downstream workflows, although this script itself does not execute such instructions. ### Attack Path 1. An attacker publishes a Bilibili video with a crafted title or description, or submits crafted danmaku to a target video. 2. A user invokes the Skill to export that video's content ...[truncated 970 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
main.py:58
Finding

Unbounded Network Response and Decompression Can Exhaust Local Resources

Content
View full analysis
list: """获取视频所有弹幕""" url = f"https://api.bilibili.com/x/v1/dm/list.so?oid={cid}" resp = requests.get(url, headers=DEFAULT_HEADERS, timeout=15) resp.encoding = 'utf-8' danmakus = [] type_map = {1: '滚动', 4: '底端', 5: '顶端', 6: '逆向', 7: '高级', 8: '代码'} try: root = ET.fromstring(resp.text) for d in root.findall('d'): p = d.get('p', '').split(',') if len(p) >= 5: danmakus.append({ 'text': d.text or '', 'time': float(p[0]), 'type': type_map.get(int(p[1]), '未知'), 'type_code': int(p[1]), 'color': p[3], 'timestamp': int(p[4]) }) except ET.ParseError: import zlib try: decompressed = zlib.decompress(resp.content) root = ET.fromstring(decompressed.decode('utf-8')) for d in root.findall('d'): p = d.get('p', '').split(',') if len(p) >= 5: danmakus.append({ 'text': d.text or '', 'time': float(p[0]), 'type': type_map.get(int(p[1]), '未知'), 'type_code': int(p[1]), 'color': p[3], 'timestamp': int(p[4]) }) except Exception as e: print(f"弹幕解压解析失败: {e}") return danmakus ``` ### Technical Analysis `requests.get()` is used without streaming or a maximum accepted response size. Accessing `resp.text` and `resp.content` buffers the complete response in memory. If initial XML parsing fails, `zlib.decompress()` expands the entire compressed payload ...[truncated 1691 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Open-Ended Dependency Constraint Prevents Reproducible Installation

Content
View full analysis
=2.28.0 ``` ### Technical Analysis The dependency declaration specifies only a minimum version and permits installation of any later `requests` release. Consequently, the package version installed in the future may differ from the version assessed during this audit. This is not evidence that the current dependency is malicious. The risk is that installation is not reproducible and may automatically incorporate an unreviewed future version or a changed transitive dependency set. The documentation further recommends `pip install requests`, which is likewise unpinned. ### Attack Path 1. The Skill is installed or rebuilt at a later date. 2. The package resolver selects the newest release satisfying `requests>=2.28.0`, along with its then-current transitive dependencies. 3. That dependency set has not necessarily undergone the same review as the Skill. 4. A compromised, vulnerable, or behaviorally incompatible future package release is installed. 5. Because Python packages execute with the privileges of the installing or running account, malicious package installation or runtime behavior could affect that account's environment. This is a supply-chain hardening issue rather than a confirmed malicious-package attack in the current project. ### Impact Assessment If a future dependency release or transitive package were compromised, it could execute with the permissions of the Python installation or Skill process. Potential scope could include files, environment variables, and network access available to that account. Under the currently reviewed source, no malicious dependency source, typosquatted package name, or dependency-confusion configuration was identified. The immediate risk is therefore low and primarily concerns reproducibility and future supply-chain exposure. ] ...[truncated 2 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill describes behavior that performs network access to Bilibili APIs and writes output files locally, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates a transparency and policy-enforcement gap: an agent or user may invoke the skill without clear boundaries on what capabilities it will use, increasing the risk of unintended file writes or outbound requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The user-facing description emphasizes danmaku extraction but does not clearly warn that the skill will send requests to external Bilibili endpoints and persist retrieved content to local files. This omission weakens informed consent and may expose user activity, queried video identifiers, or locally stored extracted data in environments where network use and file creation require explicit disclosure.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 59)May include surrounding context.

md
def get_video_info(bvid: str) -> dict:
    """获取视频信息"""
    url = f"https://api.bilibili.com/x/web-interface/view?bvid={bvid}"
    resp = requests.get(url, headers=DEFAULT_HEADERS, timeout=10)
    data = resp.json()
    if data['code'] == 0:

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 · SKILL.md (reported line 60)May include surrounding context.

md
def get_video_info(bvid: str) -> dict:
    """获取视频信息"""
    url = f"https://api.bilibili.com/x/web-interface/view?bvid={bvid}"
    resp = requests.get(url, headers=DEFAULT_HEADERS, timeout=10)
    data = resp.json()
    if data['code'] == 0:

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 · main.py (reported line 36)May include surrounding context.

python
def get_video_info(bvid: str) -> dict:
    """获取视频信息"""
    url = f"https://api.bilibili.com/x/web-interface/view?bvid={bvid}"
    resp = requests.get(url, headers=DEFAULT_HEADERS, timeout=10)
    data = resp.json()
    if data['code'] == 0:

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 · main.py (reported line 56)May include surrounding context.

python
def get_video_info(bvid: str) -> dict:
    """获取视频信息"""
    url = f"https://api.bilibili.com/x/web-interface/view?bvid={bvid}"
    resp = requests.get(url, headers=DEFAULT_HEADERS, timeout=10)
    data = resp.json()
    if data['code'] == 0:

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency is specified as requests>=2.28.0, which allows installation of any later version and does not guarantee reproducible builds. This is risky because future installs may resolve to a vulnerable or breaking release, and the accompanying advisory context shows that affected versions of requests exist, making the actual security posture unverifiable at install time.

Content

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

text
requests>=2.28.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +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

Because the manifest does not pin the requests version, it is impossible to determine whether deployments will use a release affected by known CVEs. In a network-facing tool that fetches remote Bilibili resources, an unsafe requests version could expose the skill to issues such as credential leakage, request handling flaws, or other client-side vulnerabilities depending on runtime usage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.