Back to skill

Security audit

BT Download

Security checks for vulnerabilities and agentic risk

Overview

This BT download skill is mostly coherent, but it starts a persistent unauthenticated RPC service and contains unsafe shell execution paths that need review before installation.

Install only if you are comfortable with a Chinese-language BT tool that can install aria2, start a long-running download service, enable DHT/seeding, and read local .torrent files. Prefer a revised version that removes automatic sudo installation, starts aria2 without shell interpolation, binds RPC to localhost, uses an RPC secret, and provides explicit controls to stop the background service.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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

Error
Location
plugin.ts:217
Finding

Shell Command Injection Through the Download Directory Parameter

Content
View full analysis
/tmp/aria2-rpc.log 2>&1 &`; exec(cmd, (err2) => { ``` ### Technical Analysis The `downloadDir` value can be supplied through the `bt_start_rpc` tool and is interpolated directly into a command string executed by `child_process.exec`. Although it is surrounded by double quotes, the value is not escaped or validated. Because `exec` invokes the command through a shell, a malicious value containing a double quote followed by shell metacharacters can terminate the `--dir` argument and append another command. Quoting the interpolated value is therefore insufficient to prevent command injection. The vulnerable operation runs with the same operating-system privileges as the plugin host. The input schema does not provide a security boundary and cannot replace contextual shell escaping or shell-free process execution. ### Attack Path 1. An attacker or untrusted agent invocation calls `bt_start_rpc`. 2. The attacker supplies a crafted `downloadDir` containing a closing quote and shell syntax. 3. The handler inserts the value into the `cmd` template without validation or escaping. 4. `child_process.exec` passes the resulting string to the operating-system shell. 5. The shell interprets the injected metacharacters and executes the appended command. 6. The injected command runs with the privileges of the OpenClaw/plugin process. ### Impact Assessment Successful exploitation permits arbitrary command execution under the plugin process's user account. Depending on that account's permissions, an attacker could: - Read, modify, or delete fi ...[truncated 554 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
plugin.ts:217
Finding

Unauthenticated aria2 RPC Service Exposed on All Network Interfaces

Content
View full analysis
/tmp/aria2-rpc.log 2>&1 &`; ``` The RPC client is configured to use the local endpoint, but it supplies no authentication token: ```typescript const RPC_URL = "http://localhost:6800/jsonrpc"; async function rpcCall(method: string, params: any[] = []): Promise { const { default: fetch } = await import("node-fetch"); const response = await fetch(RPC_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", method, params, id: Date.now(), }), }); const data = await response.json(); return data.result; } ``` ### Technical Analysis The aria2 process is started with `--rpc-listen-all`, which makes its JSON-RPC listener available through non-loopback network interfaces. The startup command does not configure `--rpc-secret`, and the RPC client does not send an aria2 `token:` authentication parameter. Consequently, hosts capable of reaching TCP port 6800 may invoke the exposed aria2 RPC API without authentication. Binding a service to all interfaces unnecessarily expands access beyond the local plugin and violates least privilege because the plugin itself only communicates with `localhost`. ### Attack Path 1. The user invokes `bt_start_rpc` on a host reachable by other systems. 2. The plugin starts aria2 with `--rpc-listen-all` and no RPC secret. 3. TCP port 6800 becomes reachable on the host's non-loopback interfaces unless an external firewall blocks it. 4. An attacker discovers or already knows the exposed port. 5. Th ...[truncated 1110 chars]
Remediation
View remediation
``` Apply the following hardening measures: 1. Generate the secret using a cryptographically secure random source. 2. Store the secret in a protected secret store or permission-restricted configuration file, not in source code or logs. 3. Include `token:` as the first parameter in every aria2 JSON-RPC request. 4. Avoid returning or logging the secret. 5. Restrict TCP port 6800 with host and network firewall rules. 6. If remote RPC access is necessary, place it behind an authenticated, encrypted proxy and allow only trusted clients. 7. Run aria2 under a dedicated, unprivileged account with access only to an approved download directory. 8. Verify service readiness through the authenticated RPC client rather than an unauthenticated `curl` command. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description frames the skill as a BT download helper, but the documented behavior includes installing software, invoking sudo apt-get, modifying aria2 configuration, reading local torrent files, fetching remote tracker lists, and starting a persistent RPC daemon. That mismatch is dangerous because users and policy systems may underestimate the privilege, persistence, and network effects of the skill, leading to consent bypass and execution of higher-risk actions than expected.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill’s stated purpose is download assistance, but it also performs system-level installation and service management. This expands its privilege and behavior far beyond a narrowly scoped downloader, creating unexpected host modification risk and increasing the chance an agent could make persistent system changes without informed user approval.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The tool runs 'sudo apt-get update && sudo apt-get install -y aria2', which performs privileged package management on the host. Allowing an agent skill to trigger root-level installation is dangerous because it changes the system state, may prompt for or rely on elevated privileges, and could be abused to install or chain additional software in environments where the skill is invoked automatically.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The chained shell expression 'which aria2c || (sudo apt-get update && sudo apt-get install -y aria2)' combines environment probing with privileged installation in one command. Chained admin actions reduce transparency, complicate auditing, and make it easier for an agent-triggered workflow to perform multiple sensitive operations automatically.

Content

Scanner excerpt · plugin.ts (reported line 70)May include surrounding context.

ts
const { exec } = await import("child_process");
        return new Promise((resolve) => {
          exec(
            "which aria2c || (sudo apt-get update && sudo apt-get install -y aria2)",
            (err, stdout, stderr) => {
              if (err) {
                resolve({ success: false, message: "安装失败: " + stderr });

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill advertises operational capabilities that require shell, network, and environment access, but it does not declare any explicit tool scope or permission boundaries. This is dangerous because a downloader that can install packages, start background services, and access local files expands the attack surface and makes unintended or unauthorized execution harder to govern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The description and user-facing guidance are written entirely in Chinese, and the confirmation flow explicitly instructs the user to reply with Chinese text such as “回复「1」使用默认目录”. This creates a language/locale constraint without documenting user choice or opt-in, which matches the policy category for language policy violations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The plugin's user-facing description, tool descriptions, prompts, and status messages are written in Chinese throughout the file. There is no indication that users can choose their language or that the Chinese-only behavior is a documented, justified locale constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The plugin installs packages via sudo without a distinct user-facing warning or confirmation flow. Silent or implicit privileged changes are dangerous in agent settings because the user may believe they are only invoking a download helper, while the skill is actually modifying the operating system.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
99% confidence
Finding

The presence of 'sudo' means the skill attempts privileged execution on the host. In an agent setting, privileged command paths are especially dangerous because they can alter the system broadly, may be combined with other behaviors, and exceed the expectations of a normal download assistant.

Content

Scanner excerpt · plugin.ts (reported line 70)May include surrounding context.

ts
const { exec } = await import("child_process");
        return new Promise((resolve) => {
          exec(
            "which aria2c || (sudo apt-get update && sudo apt-get install -y aria2)",
            (err, stdout, stderr) => {
              if (err) {
                resolve({ success: false, message: "安装失败: " + stderr });

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The tool starts a background RPC service, enables DHT, selects a download directory, and writes logs to /tmp without a strong disclosure/consent boundary. In an agent context, this can result in unintended persistence, network activity, and file writes that the user did not clearly authorize.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code spawns shell commands and launches a background aria2 daemon with nohup, causing persistent local service execution outside the immediate tool invocation. This is risky because it creates a long-lived process, opens an RPC interface, and writes logs/files, all of which increase attack surface and can surprise users or be misused in shared environments.

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 · plugin.ts (reported line 190)May include surrounding context.

ts
return new Promise((resolve) => {
          // 检查 RPC 是否已启动
          exec("curl -s http://localhost:6800/jsonrpc -d '{\"jsonrpc\":\"2.0\",\"method\":\"aria2.getVersion\",\"id\":1}'", async (err) => {
            if (!err) {
              // RPC 已启动,检测 DHT 状态
              if (enableDht) {

Session Persistence

Medium
Category
Rogue Agent
Confidence
95% confidence
Finding

Using nohup to launch aria2 creates session persistence beyond the lifetime of the immediate interaction. Persistent background processes are risky because they continue network activity and file operations after the user may believe the tool has finished, and they enlarge the local attack surface via the RPC service.

Content

Scanner excerpt · plugin.ts (reported line 217)May include surrounding context.

ts
// 启动 RPC 服务,带 DHT 参数
            const dhtArgs = enableDht ? "--enable-dht --enable-dht6" : "";
            const cmd = `nohup aria2c --enable-rpc --rpc-listen-all \
              ${dhtArgs} \
              --dir="${downloadDir}" \
              --seed-ratio=${seedRatio} \

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The plugin fetches tracker data from a third-party GitHub-hosted source without making that network disclosure obvious to the user. While not inherently malicious, it exposes user environments to external requests and introduces trust and integrity concerns around remote content used to influence BT behavior.

Content

No source excerpt is available for this finding.