Back to skill

Security audit

bilibili-universal

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Bilibili scraping purpose, but it has review-worthy risks around global browser-session closure, unsafe shared temporary storage, under-warned login cookie handling, and unpinned optional dependencies.

Install only if you are comfortable with a Bilibili scraper that can use authenticated browser state and write harvested public/user-linked data locally. Avoid placing real account cookies in the skill directory unless necessary, keep any cookie file private and out of version control, set `BI_DATA_DIR` to a user-private directory instead of relying on `/tmp`, and review the unpinned Python dependencies before enabling danmaku features.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (3)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:8
Finding

Unpinned Third-Party Dependencies Create a Supply-Chain Risk

Content
View full analysis
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Warning
Location
bili-fetch.py:388
Finding

Automatic Recovery Terminates All Agent-Browser Sessions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
paths.py:29
Finding

Predictable Shared Temporary Directory Is Trusted Without Ownership or Symlink Validation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (38)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The boundary section states '长视频弹幕导出 → agent-browser skill 自己写 (未集成)', which says danmaku export is not integrated into this skill. However, multiple earlier sections document built-in 'danmaku' subcommands and '--danmaku' harvest support, so this is an active contradiction about implemented capability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README instructs users to place live authentication cookies such as SESSDATA and bili_jct into a local file, but it does not explicitly warn that these values are credentials that can grant account access or expose private account state. In a scraping skill context, normalizing manual cookie injection without security guidance increases the chance that users mishandle, commit, or share sensitive tokens.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 63)May include surrounding context.

想拿更高画质/关注状态? 注入 cookie (可选)

echo "buvid3=xxx; SESSDATA=xxx; bili_jct=xxx; ..." > data/cookies-raw.txt chmod 600 data/cookies-raw.txt

用 agent-browser --state 或手动加载

text

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 250)May include surrounding context.

想拿更高画质/关注状态? 注入 cookie (可选)

echo "buvid3=xxx; SESSDATA=xxx; bili_jct=xxx; ..." > data/cookies-raw.txt chmod 600 data/cookies-raw.txt

用 agent-browser --state 或手动加载

text

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises and documents capabilities that imply shell, file, environment, and network access, but it does not declare an explicit tool scope or permissions boundary. In an agent ecosystem, that omission increases the chance the skill is run with broader privileges than necessary, enabling unnecessary file access, credential exposure, or arbitrary outbound requests if the implementation is compromised or misused.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description states the skill '自动复用 buvid cookie + wbi 签名环境', implying use of a WBI signing environment. Later documentation explicitly says '本 skill 所有命令不直接调 wbi 接口' and '完全不需要算 w_rid', which contradicts that earlier claim rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup instructions tell users to copy sensitive Bilibili cookies including SESSDATA and bili_jct into a local file, but they do not clearly warn that these values are authentication credentials that can enable account access or abuse if leaked. In a scraping-oriented skill that stores data on disk and interacts with browser state, this materially raises the risk of credential theft, accidental commit, or unsafe sharing.

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-fetch.py (reported line 75)May include surrounding context.

python
def run(cmd, timeout=30, check=False):
    """跑 agent-browser 命令"""
    r = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
    if check and r.returncode != 0:
        print(f"  stdout: {r.stdout[:300]}")
        print(f"  stderr: {r.stderr[:300]}")

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

md
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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-fetch.py (reported line 148)May include surrounding context.

python
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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-fetch.py (reported line 175)May include surrounding context.

python
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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-fetch.py (reported line 228)May include surrounding context.

python
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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-fetch.py (reported line 491)May include surrounding context.

python
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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-fetch.py (reported line 506)May include surrounding context.

python
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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-fetch.py (reported line 699)May include surrounding context.

python
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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 · docs/pitfalls.md (reported line 25)May include surrounding context.

md
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

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 · docs/pitfalls.md (reported line 33)May include surrounding context.

md
def bvid_to_aid(bvid):
    """BV 号 → aid (通过 web-interface/view 拿)"""
    js = f"""(async () => {{
      const r = await fetch('https://api.bilibili.com/x/web-interface/view?bvid={bvid}', {{credentials:'include'}});
      const j = await r.json();
      return JSON.stringify({{code: j.code, aid: j?.data?.aid, title: j?.data?.title, msg: j.message}});
    }})()"""

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · bili-fetch.py (reported line 343)May include surrounding context.

python
})()"""
                res = ab_eval(page_js)
                d = res if isinstance(res, dict) else {}
                plist = d.get('list', []) if isinstance(d, dict) else []
                next_disabled = d.get('disabled', True) if isinstance(d, dict) else True

                for bvid, title in plist:

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · bili-fetch.py (reported line 346)May include surrounding context.

python
})()"""
                res = ab_eval(page_js)
                d = res if isinstance(res, dict) else {}
                plist = d.get('list', []) if isinstance(d, dict) else []
                next_disabled = d.get('disabled', True) if isinstance(d, dict) else True

                for bvid, title in plist:

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · bili-fetch.py (reported line 351)May include surrounding context.

python
})()"""
                res = ab_eval(page_js)
                d = res if isinstance(res, dict) else {}
                plist = d.get('list', []) if isinstance(d, dict) else []
                next_disabled = d.get('disabled', True) if isinstance(d, dict) else True

                for bvid, title in plist:

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-fetch.py (reported line 392)May include surrounding context.

python
# 重试: fresh session 首次访问 SPA 偶尔不渲染, 主动 close --all + 重来一次
        if not paginated_bvids_titles:
            info("首次 抓 0, 可能是 fresh session 未能渲染, 主动 close --all + 重试")
            subprocess.run(['agent-browser', 'close', '--all'], capture_output=True, timeout=15)
            time.sleep(2)
            ab_open(space_url)
            time.sleep(8)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The comment export collects and persists user-linked metadata including username, mid, comment text, likes, and location without any user-facing disclosure or minimization. In a scraping skill that reuses browser cookies, this increases privacy risk and can facilitate profiling or bulk collection of personal data beyond what a user may expect.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

While the outbound request itself is expected, this specific call retrieves comment data and associated user metadata using included browser credentials. In context, the more significant issue is undisclosed collection of personal data, so this network transfer meaningfully contributes to privacy risk.

Content

Scanner excerpt · bili-fetch.py (reported line 539)May include surrounding context.

python
if args.comments > 0:
        aid = detail['aid']
        comments_js = f"""(async () => {{
          const r = await fetch('https://api.bilibili.com/x/v2/reply/main?oid={aid}&type=1&mode=3&next=0&ps={args.comments}', {{credentials:'include'}});
          const j = await r.json();
          const replies = (j?.data?.replies || []).map(rp => ({{
            rpid: rp.rpid, uname: rp.member?.uname, mid: rp.member?.mid,

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill description promises scraping uniformly through agent-browser with its cookie/signing environment, but danmaku retrieval silently uses a separate bilibili_api client. That bypass changes the trust boundary, network behavior, and authentication/session assumptions, which can expose different credentials, evade expected controls, or produce unreviewed outbound traffic.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Danmaku export writes user-linked metadata such as uid_hash and sender_id to disk without explicit disclosure. Even if partially pseudonymized, these identifiers can support tracking, correlation, or deanonymization when combined with other data sources.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
bili-fetch.py:14