Back to skill

Security audit

bilibit

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Bilibili downloader, but it automatically installs and runs a third-party native downloader without integrity checks and includes a shell-enabled wrapper that can expose users to command injection risk.

Review this carefully before installing. Installing through npm can automatically download a BBDown executable from GitHub without cryptographic verification, and running the exported bbdown wrapper may allow shell metacharacters in arguments to execute unintended commands. If you use it anyway, prefer installing BBDown yourself from a source you trust, avoid passing cookie files unless necessary, inspect or clear ~/.bilibit/history.json, and do not run the package as root or from privileged automation.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install-bbdown.js:34
Finding

Automatic Retrieval and Execution of an Unverified Third-Party Binary

Content
View full analysis

Vulnerability Details

File Location: package.json:12-14; scripts/install-bbdown.js:34-52, 61-70, 84-104
Vulnerability Type: Unverified remote payload retrieval and execution
Risk Level: High

Vulnerable Code

json
"scripts": {
  "test": "node tests/",
  "start": "node bin/bilibit.js",
  "postinstall": "node scripts/install-bbdown.js"
}
js
if (platform === 'darwin') {
  if (arch === 'arm64') {
    downloadUrl = 'https://github.com/nilaoda/BBDown/releases/download/1.6.3/BBDown_1.6.3_20240814_macos-arm64.zip';
  } else {
    downloadUrl = 'https://github.com/nilaoda/BBDown/releases/download/1.6.3/BBDown_1.6.3_20240814_macos-x64.zip';
  }
} else if (platform === 'linux') {
  if (arch === 'arm64') {
    downloadUrl = 'https://github.com/nilaoda/BBDown/releases/download/1.6.3/BBDown_1.6.3_20240814_linux-arm64.zip';
  } else {
    downloadUrl = 'https://github.com/nilaoda/BBDown/releases/download/1.6.3/BBDown_1.6.3_20240814_linux-x64.zip';
  }
} else if (platform === 'win32') {
  binaryName = 'BBDown.exe';
  downloadUrl = 'https://github.com/nilaoda/BBDown/releases/download/1.6.3/BBDown_1.6.3_20240814_win-x64.zip';
}
js
const installDir = path.join(__dirname, '..', 'node_modules', '.bin');
const zipPath = path.join(installDir, 'bbdown.zip');

const curl = spawn('curl', ['-L', '-o', zipPath, downloadUrl], { stdio: 'ignore' });

const unzip = spawn('unzip', ['-o', '-q', zipPath, '-d', installDir], { stdio: 'ignore' });

const installPath = path.join(installDir, binaryName);

if (!fs.existsSync(installPath)) {
  console.log('❌ 解压后未找到 BBDown 二进制文件');
  console.log('安装目录内容:', fs.readdirSync(installDir));
  resolve(false);
  return;
}

fs.chmodSync(installPath, '755');

Technical Analysis

The npm postinstall lifecycle automatically downloads a platform-specific BBDown archive, extracts it into the package's executable directory, and m ...[truncated 2344 chars]

Remediation
View remediation

Remediation Suggestions

  1. Publish a trusted manifest containing a distinct SHA-256 or stronger digest for every supported archive.
  2. Embed or securely pin those expected digests in the reviewed npm package and verify the downloaded bytes before extraction.
  3. Fail closed and delete the archive if verification fails. Never make an unverified file executable.
  4. Verify a signed release manifest or platform-native code signature against a pinned publisher identity where available.
  5. Restrict redirects to an explicit allowlist of HTTPS hosts, or avoid unrestricted curl -L.
  6. Validate every archive entry before extraction and reject absolute paths, parent-directory traversal, links, unexpected executables, and duplicate entries.
  7. Download to a private temporary directory using unpredictable names and restrictive permissions.
  8. Prefer making BBDown an explicit prerequisite or require informed installation consent rather than retrieving native code automatically during postinstall.
  9. Document the exact upstream source, version, digests, cookie exposure, and verification procedure.
  10. Run the downloader with the least available privileges and, where practical, sandbox its filesystem and network access.

T09 · Insecure Skill Coding Practices

Error
Location
bin/bbdown-wrapper.js:8
Finding

Command Injection Through Shell-Enabled BBDown Wrapper

Content
View full analysis

Vulnerability Details

File Location: bin/bbdown-wrapper.js:8-17
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

js
const { spawnSync } = require('child_process');
const path = require('path');

const bbdownPath = path.join(__dirname, '..', 'node_modules', '.bin', 'BBDown');

const args = process.argv.slice(2);

const result = spawnSync(bbdownPath, args, {
  stdio: 'inherit',
  shell: true
});

Technical Analysis

The package exports this file as the bbdown command. Every command-line argument is attacker-controllable through process.argv, and spawnSync is invoked with shell: true.

Shell-enabled process creation causes the executable and argument sequence to be interpreted through the platform command shell. Arguments containing shell metacharacters can therefore alter command structure instead of being passed literally to BBDown. Depending on the platform shell, relevant syntax may include command separators, command substitution, redirection, pipelines, or environment expansion.

This behavior is unnecessary. BBDown is a concrete executable with an argument-array interface, and Node.js can invoke it directly without a shell. The main downloader implementation already uses direct spawn(bbdownPath, args, ...), demonstrating the safer pattern.

Attack Path

  1. An attacker supplies a crafted URL or BBDown argument containing shell syntax to a user, automation system, or AI Agent.
  2. The untrusted value is passed to the package's exported bbdown command.
  3. bbdown-wrapper.js copies the value into process.argv.
  4. spawnSync starts a command shell because shell: true is enabled.
  5. The shell interprets the crafted metacharacters as command syntax.
  6. The injected command executes with the privileges and environment of the calling process.

Exploitation is especially plausible where an Agent or service builds CLI invocations from remo ...[truncated 580 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove shell interpretation and invoke the binary directly:
js
const result = spawnSync(bbdownPath, args, {
  stdio: 'inherit',
  shell: false
});
  1. Since false is the default, omitting the shell property is also acceptable.
  2. Confirm that bbdownPath resolves to the intended regular executable and is not a symbolic link to an unexpected target.
  3. Validate options against an allowlist when this wrapper is called by an Agent or network-facing service.
  4. Treat URLs as opaque individual arguments and never construct a command string from them.
  5. Add regression tests using platform-relevant separators, command substitutions, quotes, redirects, and whitespace to verify that each value reaches BBDown as one literal argument.
  6. Return a distinct failure status when process creation fails; do not convert a null status to success through result.status || 0.

T09 · Insecure Skill Coding Practices

Note
Location
src/utils/history.js:12
Finding

Download History Is Stored Without Explicit Private Permissions

Content
View full analysis

Vulnerability Details

File Location: src/utils/history.js:12-19, 46-53; data originates from src/cli.js:99-108
Vulnerability Type: Insecure local storage of private activity metadata
Risk Level: Low

Vulnerable Code

js
function getHistoryFilePath() {
  const homeDir = process.env.HOME || process.env.USERPROFILE;
  const configDir = path.join(homeDir, '.bilibit');

  if (!fs.existsSync(configDir)) {
    fs.mkdirSync(configDir, { recursive: true });
  }

  return path.join(configDir, 'history.json');
}
js
function saveHistory(history) {
  const filePath = getHistoryFilePath();

  try {
    fs.writeFileSync(filePath, JSON.stringify(history, null, 2), 'utf8');
    return true;
  } catch (error) {
    console.error('Failed to save history:', error.message);
    return false;
  }
}

The stored records include private metadata:

js
history.addRecord({
  videoId,
  url,
  title,
  downloadPath: result.output,
  quality: options.quality || options.q,
  danmaku: options.danmaku || options.d
});

Technical Analysis

The application stores video URLs, titles, video identifiers, selected quality, and local download paths in ~/.bilibit/history.json. Neither the directory nor the file is created with an explicit restrictive mode.

Effective access therefore depends on the process umask and inherited filesystem permissions. In an environment with a permissive umask or a shared home directory, another local account or process may be able to inspect the user's viewing history and filesystem layout.

This is persistent application data, but it does not contain Agent instructions and is not used to alter future Agent behavior. It is therefore a local data-protection issue rather than Agent memory poisoning or system persistence.

Attack Path

  1. A user downloads one or more videos.
  2. The application writes the URL, title, and local output ...[truncated 779 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create the configuration directory with owner-only permissions:
js
fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
  1. Create and update the history file with mode 0600:
js
fs.writeFileSync(
  filePath,
  JSON.stringify(history, null, 2),
  { encoding: 'utf8', mode: 0o600 }
);
  1. Explicitly correct permissions on existing directories and files because the creation mode does not change pre-existing objects.
  2. Use an atomic private temporary file followed by a rename to avoid partial writes and reduce link-related race risks.
  3. Provide documented commands to clear history and, preferably, an option to disable history retention.
  4. Document which metadata is retained and the maximum retention count.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

Maintaining download history and accepting cookie files expands the skill's access to persistent local data beyond a minimal stateless downloader. If these behaviors are not prominently disclosed, the skill may collect or retain sensitive browsing/account artifacts in ways users and reviewers did not anticipate.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Maintaining download history and accepting cookie files expands the skill's access to persistent local data beyond a minimal stateless downloader. If these behaviors are not prominently disclosed, the skill may collect or retain sensitive browsing/account artifacts in ways users and reviewers did not anticipate.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Maintaining download history and accepting cookie files expands the skill's access to persistent local data beyond a minimal stateless downloader. If these behaviors are not prominently disclosed, the skill may collect or retain sensitive browsing/account artifacts in ways users and reviewers did not anticipate.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
84% confidence
Finding

The script chains multiple privileged commands in one execSync shell invocation using '&&'. Although no untrusted input is interpolated here, shell chaining increases risk by broadening what runs with elevated privileges and making review, auditing, and failure handling weaker than discrete validated steps.

Content

Scanner excerpt · scripts/check-deps.js (reported line 40)May include surrounding context.

js
} else if (platform === 'linux') {
      // Linux
      console.log('检测到 Linux,使用 apt 安装...');
      execSync('sudo apt update && sudo apt install -y bbdown', { stdio: 'inherit' });
    } else if (platform === 'win32') {
      // Windows
      console.log('检测到 Windows,请手动安装:');

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

L077 explicitly states that the current SKILL.md promises search even though the code does not implement it, which is an active contradiction between declared intent and actual behavior. This is a direct documentation-versus-implementation divergence relevant to the skill's stated boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README states that BBDown auto-installs during installation, but it does not clearly warn users that installing this package will also fetch and execute an additional dependency as part of setup. Silent or poorly disclosed secondary installation increases supply-chain risk because users may not realize another binary/tool is being introduced into their environment, potentially with its own trust, licensing, and execution implications.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes the skill as a pure Bilibili download tool that supports video and danmaku downloads and explicitly says it does not support search. This README adds materially different behavior—automatic BBDown installation and maintaining/viewing download history—which goes beyond the stated manifest scope rather than merely explaining download implementation details.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README states that BBDown will be installed automatically, but it does not clearly warn that this causes software download and installation actions on the user's system. For an agent-integrated skill, undocumented installation side effects can reduce informed consent and increase supply-chain risk, especially if users expect a simple downloader rather than a tool that fetches and installs another executable.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding

The skill advertises executable dependencies (bbdown, ffmpeg) and the analyzer detected shell/environment capabilities, but the manifest does not declare an explicit tool scope such as permissions or allowed-tools. In an agent setting, undeclared execution capability reduces reviewability and can allow the skill to invoke shell behavior beyond what users expect from a simple downloader.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Broad trigger phrases tied to a major platform name can cause the skill to activate on casual mentions rather than clear requests to download content. In an agent environment, unintended invocation can lead to unexpected network access, shell execution, or handling of URLs/files when the user did not intend to use this skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Aliases like '哔哩哔哩', 'B 站', '视频下载', and '弹幕下载' are too vague and overlap with ordinary conversation. This increases the chance of accidental routing into a tool that may invoke shell/network behavior, making the skill more dangerous than its benign downloader context would otherwise suggest.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The trigger examples include ambiguous natural-language phrases that do not cleanly separate activation from general discussion of Bilibili content. Ambiguous routing rules are risky because they can cause unintentional execution of a downloader skill in contexts where the user is only asking about videos or discussing the platform.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The wrapper passes user-controlled CLI arguments into spawnSync with shell:true, which causes execution through a shell rather than directly invoking the BBDown binary. This expands the attack surface from 'download a video' to potential shell metacharacter interpretation and command injection, making the wrapper more dangerous than the skill description implies.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script invokes a local executable via spawnSync and passes through arbitrary command-line arguments, but it provides no confirmation prompt, visible warning, or user-facing disclosure beyond a brief code comment. For code files, subprocess execution is a safety-relevant operation that should have some explicit disclosure unless clearly communicated elsewhere.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file’s comments and all user-facing console messages are written in Chinese, indicating the skill is designed to operate in a fixed language without user opt-in or an alternative locale. Under the policy rule, forcing a specific language without offering a choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
89% confidence
Finding

The install helper invokes 'sudo apt update && sudo apt install -y bbdown' through execSync, causing the skill to trigger privileged system package operations. Even with a hardcoded command, automatically prompting users into root-level installation from a skill increases the blast radius of compromise and can modify the host outside the skill's normal scope.

Content

Scanner excerpt · scripts/check-deps.js (reported line 40)May include surrounding context.

js
} else if (platform === 'linux') {
      // Linux
      console.log('检测到 Linux,使用 apt 安装...');
      execSync('sudo apt update && sudo apt install -y bbdown', { stdio: 'inherit' });
    } else if (platform === 'win32') {
      // Windows
      console.log('检测到 Windows,请手动安装:');

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/check-deps.js (reported line 55)May include surrounding context.

js
} catch (error) {
    console.log('\n⚠️  BBDown 安装失败,请手动安装:');
    console.log('   macOS: brew install bbdown');
    console.log('   Linux: sudo apt install bbdown');
    console.log('   Windows: https://github.com/nilaoda/BBDown/releases\n');
    return false;
  }

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest explicitly says the skill is a pure download tool and does not support search. However, the post-install/help output tells users to run bilibit search "LOL 集锦", which presents search as a supported capability and conflicts with the stated skill scope.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script's inline usage guidance functions as documentation for the tool, and it actively instructs users to use a search command. That contradicts the stated intent that the skill does not support search, creating intent-code/documentation divergence.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code presents core user-facing status messages in Chinese, and the help text also mixes Chinese-only guidance with English labels. The file does not offer any user opt-in, locale selection, or documented justification for forcing this language choice, which fits the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

This file presents all operational instructions in Chinese, which can constitute a language policy concern if users are not given an in-file choice or opt-in for locale. Although it links to English documentation, the file itself does not offer language selection within the instructions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The comment string "B 站视频下载专家" presents the skill identity in Chinese only, which suggests a language-specific experience. Under the policy for natural-language violations, forcing a specific language without documented user choice or justification can be noncompliant.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code formats timestamps using toLocaleString('zh-CN', ...), which forces a specific locale for all users. This is a natural-language/locale policy concern because the skill does not offer user opt-in or configuration for language/locale behavior, and no region-specific justification is present in the file.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
bin/bbdown-wrapper.js:15

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/check-deps.js:17

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/install-bbdown.js:18

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/downloader/bbdown.js:57