Back to skill

Security audit

Aria2 Download

Security checks for vulnerabilities and agentic risk

Overview

This is a real Aria2 download helper, but it needs review because its documented network setup and shell parsing can expose download control or local code execution.

Review before installing. Use only a trusted localhost or private-network Aria2 RPC endpoint, require a strong unique secret and TLS or equivalent network protection for remote use, avoid exposing port 6800 publicly, pin any Docker image, and patch the script to build JSON with a real encoder and parse RPC responses as data rather than interpolating them into node -e.

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

Error
Location
download.sh:95
Finding

Arbitrary Local Code Execution Through JavaScript Source Injection

Content
View full analysis
0 ? ((completed / total) * 100).toFixed(1) : 0; const filename = s.files && s.files[0] ? s.files[0].path : 'unknown'; const name = filename.split('/').pop(); console.log(JSON.stringify({ success: true, gid: '$GID', status: s.status, name: name, total: total, completed: completed, speed: speed, speedHuman: speed > 1024*1024 ? (speed/1024/1024).toFixed(1)+'MB/s' : (speed/1024).toFixed(1)+'KB/s', percent: percent + '%', eta: speed > 0 ? Math.round((total - completed) / speed) + 's' : null })); " ``` A second vulnerable interpolation occurs in the wait and watch implementation: ```bash node -e " const r = JSON.parse('$RESPONSE'); const s = r.result || {}; const status = s.status; const total = parseInt(s.totalLength) || 0; const completed = parseInt(s.completedLength) || 0; const speed = parseInt(s.downloadSpeed) || 0; const percent = total > 0 ? ((completed / total) * 100).toFixed(1) : 0; const filename = s.files && s.files[0] ? s.files[0].path.split('/').pop() : 'unknown'; const dir = s.dir || '$DIR'; const totalSize = (total / 1024 / 1024).toFixed(2); const completedSize = (completed / 1024 / 1024).toFixed(2); if (status === 'complete') { console.log(''); console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); console.log('✅ 下载完成!'); console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); cons ...[truncated 3107 chars]
Remediation
View remediation
{ input += chunk; }); process.stdin.on("end", () => { try { const response = JSON.parse(input); // Process response values only as data. } catch (error) { console.error(JSON.stringify({ success: false, error: "Invalid RPC response" })); process.exit(1); } }); ' ``` Pass GID and directory values as separate environment variables or command-line arguments rather than embedding them in source. Validate GIDs against the expected Aria2 GID format before use. Additional hardening should include: 1. Reject malformed or unexpectedly large RPC responses. 2. Validate the RPC response schema and field types before processing. 3. Avoid `node -e` when a fixed, separately stored script can be used. 4. Require authenticated and trusted RPC endpoints. 5. Use TLS certificate verification for remote RPC services. 6. Run the utility under a minimally privileged account. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
download.sh:20
Finding

Unsafe JSON-RPC Construction and Plaintext Secret Transmission

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:106
Finding

Unpinned Third-Party Container Image in Installation Instructions

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (11)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation instructs users to expose Aria2 RPC on all interfaces via --rpc-listen-all=true and to publish port 6800 in Docker, without warning about restricting access or using network protections. An exposed RPC endpoint protected only by a weak/shared secret can allow unauthorized remote control of downloads, file placement, and service abuse from other hosts.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documents shell-based operational capability but does not declare an explicit tool scope such as permissions or allowed-tools. This weakens least-privilege boundaries and can cause an agent runtime to expose broader shell access than users expect, especially for a download-oriented skill that may handle untrusted URLs and local files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation includes plaintext examples for ARIA2_SECRET and normalizes handling the RPC credential directly in shell environment variables without warning users about leakage risks. Secrets placed in shell history, screenshots, logs, process environments, or shared docs can be reused to control the Aria2 RPC service.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The script sends user-controlled data such as URL, filename, directory, and optional RPC secret to an external RPC endpoint without validating the destination or safely encoding JSON fields. Because RPC_URL can point to any host and the payload is assembled by string interpolation, this can enable data exfiltration to attacker-controlled endpoints and JSON/command-breaking injection paths via crafted input or malicious RPC responses.

Content

Scanner excerpt · download.sh (reported line 33)May include surrounding context.

sh
RPC_PAYLOAD="{\"jsonrpc\":\"2.0\",\"method\":\"aria2.addUri\",\"id\":1,\"params\":[[\"URL\"],$OPTIONS_JSON]}"
  fi
  
  RESPONSE=$(curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" -d "$RPC_PAYLOAD")
  
  if echo "$RESPONSE" | grep -q '"error"'; then
    ERROR_MSG=$(echo "$RESPONSE" | grep -oP '"message":\s*"\K[^"]+' | head -1)

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · download.sh (reported line 59)May include surrounding context.

sh
RPC_PAYLOAD="{\"jsonrpc\":\"2.0\",\"method\":\"aria2.tellStatus\",\"id\":1,\"params\":[\"$GID\"]}"
  fi
  
  RESPONSE=$(curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" -d "$RPC_PAYLOAD")
  
  if echo "$RESPONSE" | grep -q '"error"'; then
    echo "{\"success\": false, \"error\": \"查询失败\"}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · download.sh (reported line 224)May include surrounding context.

sh
RPC_PAYLOAD="{\"jsonrpc\":\"2.0\",\"method\":\"aria2.tellStatus\",\"id\":1,\"params\":[\"$GID\"]}"
  fi
  
  RESPONSE=$(curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" -d "$RPC_PAYLOAD")
  
  if echo "$RESPONSE" | grep -q '"error"'; then
    echo "{\"success\": false, \"error\": \"查询失败\"}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The script embeds the raw RPC response inside a single-quoted JavaScript string passed to node -e. If a malicious or compromised RPC server returns data containing quotes or crafted JavaScript fragments, this can break out of the string and result in arbitrary code execution on the local system.

Content

Scanner excerpt · download.sh (reported line 78)May include surrounding context.

sh
RPC_PAYLOAD="{\"jsonrpc\":\"2.0\",\"method\":\"aria2.tellStatus\",\"id\":1,\"params\":[\"$GID\",[\"status\",\"totalLength\",\"completedLength\",\"downloadSpeed\",\"files\"]]}"
  fi
  
  RESPONSE=$(curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" -d "$RPC_PAYLOAD")
  
  if echo "$RESPONSE" | grep -q '"error"'; then
    echo "{\"success\": false, \"error\": \"任务不存在或已完成\"}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

As in the progress path, the watch/wait logic inserts untrusted RPC response data directly into a node -e script within a quoted literal. A malicious RPC endpoint can return crafted JSON that escapes the string context and executes arbitrary JavaScript, leading to local command execution under the user's privileges.

Content

Scanner excerpt · download.sh (reported line 124)May include surrounding context.

sh
RPC_PAYLOAD="{\"jsonrpc\":\"2.0\",\"method\":\"aria2.tellStatus\",\"id\":1,\"params\":[\"$GID\",[\"status\",\"totalLength\",\"completedLength\",\"downloadSpeed\",\"files\",\"fileSize\",\"dir\"]]}"
    fi
    
    RESPONSE=$(curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" -d "$RPC_PAYLOAD" 2>/dev/null)
    
    if echo "$RESPONSE" | grep -q '"error"'; then
      echo ""

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description and the entire user-facing documentation are written in Chinese, with no indication that language selection is configurable or intentionally limited to a Chinese-speaking audience. The policy requires avoiding language or locale constraints unless users are given a choice or the restriction is clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The usage text and status messages include Chinese user-facing strings such as '添加下载' and '查询下载状态' while other parts are in English. This imposes a locale on users without any documented opt-in or language-selection mechanism, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.