Back to skill

Security audit

Aria2 Json Rpc

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a legitimate aria2 controller, but it handles RPC secrets and destructive download actions without enough built-in safeguards.

Review before installing if your aria2 RPC uses a secret or a remote host. Prefer localhost or HTTPS/WSS, set config files to owner-only permissions, and require explicit confirmation before removing, purging, pausing all downloads, changing global options, or adding torrents.

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
scripts/config_loader.py:286
Finding

RPC Credentials Can Be Transmitted Over Unencrypted HTTP or WebSocket Connections

Content
View full analysis

Vulnerability Details

File Location: scripts/config_loader.py:286-313, scripts/rpc_client.py:56-62, 77-79, 119-137, scripts/websocket_client.py:65-70, 87-89, 166-181
Vulnerability Type: Plaintext transmission of sensitive authentication data
Risk Level: Medium

Vulnerable Code

scripts/config_loader.py:286-313:

python
# Build URL
protocol = "https" if self.config["secure"] else "http"
path = self.config.get("path") or ""
url = f"{protocol}://{self.config['host']}:{self.config['port']}{path}"

# Create a simple test request (aria2.getVersion)
request_data = {
    "jsonrpc": "2.0",
    "id": "test-connection",
    "method": "aria2.getVersion",
    "params": [],
}

# Add token if configured
if self.config.get("secret"):
    request_data["params"].insert(0, f"token:{self.config['secret']}")

try:
    req = urllib.request.Request(
        url,
        data=json.dumps(request_data).encode("utf-8"),
        headers={"Content-Type": "application/json"},
    )

    timeout_sec = self.config["timeout"] / 1000.0
    response = urllib.request.urlopen(req, timeout=timeout_sec)

scripts/rpc_client.py:56-62, 77-79, 119-137:

python
def _build_endpoint_url(self) -> str:
    """Build the full RPC endpoint URL."""
    protocol = "https" if self.config.get("secure", False) else "http"
    host = self.config["host"]
    port = self.config["port"]
    path = self.config.get("path") or ""
    return f"{protocol}://{host}:{port}{path}"

def _inject_token(self, params: List[Any]) -> List[Any]:
    secret = self.config.get("secret")
    if secret:
        return [f"token:{secret}"] + params
    return params

request_data = json.dumps(request).encode("utf-8")

req = urllib.request.Request(
    self.endpoint_url,
    data=request_data,
    headers={
        "Content-Type": "application/json",
        "User-Agent": "aria2-json-rpc-client/1.0",
    }
...[truncated 2893 chars]
Remediation
View remediation

Remediation Suggestions

  1. Reject configurations that combine a non-loopback host, a nonempty secret, and secure=false.
  2. Permit plaintext authenticated transport only for verified loopback addresses such as 127.0.0.1 and ::1.
  3. If legacy remote plaintext support is unavoidable, require a clearly named explicit override such as allow_insecure_remote_auth, disabled by default.
  4. Emit a prominent warning before any insecure connection attempt; do not rely solely on documentation.
  5. Default remote configurations to HTTPS/WSS and document certificate validation requirements.
  6. Consider separating local and remote configuration profiles so that a local plaintext default cannot be accidentally reused for a remote server.
  7. Add tests confirming that secrets cannot be sent over HTTP or WS to non-loopback destinations without explicit authorization.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config_loader.py:490
Finding

Secret-Bearing Configuration Files Are Not Enforced as Owner-Only

Content
View full analysis

Vulnerability Details

File Location: scripts/config_loader.py:490-505
Vulnerability Type: Insecure permissions for sensitive configuration
Risk Level: Medium

Vulnerable Code

python
# Create directory if needed
if not os.path.exists(target_dir):
    os.makedirs(target_dir, exist_ok=True)
    print(f"✓ Created directory: {target_dir}")

# Check if config already exists
if os.path.exists(target_file):
    response = input(
        f"Config file already exists at {target_file}\nOverwrite? [y/N]: "
    )
    if response.lower() not in ["y", "yes"]:
        print("Cancelled.")
        sys.exit(0)

# Copy example to target
shutil.copy2(example_file, target_file)
print(f"✓ Configuration initialized at: {target_file}")

Technical Analysis

The initialization process copies config.example.json using shutil.copy2. This operation preserves metadata, including the source file's permission mode, instead of explicitly creating the target as an owner-only secret file.

The initialized file initially contains no real secret, but the documented workflow instructs the user to edit this same file and add the aria2 RPC token. If the copied mode is group-readable or world-readable, that secret becomes accessible to other local users. The parent directory is also created without an explicit 0700 mode and therefore depends on the process umask.

CONFIG.md separately recommends chmod 600, but the initialization command does not enforce that recommendation. Security therefore depends on users noticing and manually applying optional documentation.

Attack Path

  1. A user runs python3 scripts/config_loader.py init --user.
  2. The script creates the configuration directory using the ambient umask and copies the example file while preserving its mode.
  3. The resulting file remains readable by a group or other local accounts.
  4. The user edits the file and stores a valid aria2 RPC secr ...[truncated 654 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create the user configuration directory with mode 0700.
  2. Create or copy the configuration file with mode 0600, independent of the source mode and process umask.
  3. Immediately call os.chmod(target_file, 0o600) after initialization and after overwriting an existing file.
  4. Validate existing configuration permissions during load, show, and test; warn or fail when a secret-bearing file is accessible by group or other users.
  5. Use atomic file creation with restrictive permissions to avoid a window in which the file has a permissive mode.
  6. For local project configuration, warn clearly when the target is inside a version-controlled directory.
  7. Retain the documentation guidance, but treat it as supplemental rather than the primary control.

T08 · Insecure Dependencies

Note
Location
scripts/dependency_check.py:90
Finding

Optional WebSocket Dependency Is Installed Without Version or Integrity Pinning

Content
View full analysis

Vulnerability Details

File Location: scripts/dependency_check.py:90-95, SKILL.md:5, scripts/examples/monitor-downloads.py:16-18
Vulnerability Type: Unpinned third-party dependency
Risk Level: Low

Vulnerable Code

scripts/dependency_check.py:90-95:

python
# Check optional websockets (Milestone 3 only)
if milestone >= 3:
    if not check_optional_websockets():
        print("WARNING: 'websockets' library not found")
        print(
            "WebSocket features will be disabled. Install with: pip install websockets"
        )

SKILL.md:5:

text
compatibility: Requires Python 3.6+. WebSocket support requires websockets package (pip install websockets) and Python version must match dependency requirements.

scripts/examples/monitor-downloads.py:16-18:

text
Requirements:
    - aria2 must be running with RPC enabled (preferably WebSocket)
    - Python websockets library: `uv pip install websockets`

Technical Analysis

The Skill instructs users to install the latest available release of the third-party websockets package without a reviewed version constraint, lock file, or package hash. This creates avoidable supply-chain and reproducibility risk: future package releases may introduce malicious behavior, incompatible API changes, or newly exploitable vulnerabilities.

The package name is legitimate, and the audit found no typosquatting, dependency confusion, automatic installation, or nonstandard package source. The risk is therefore lower than an actively malicious dependency and is limited to users who enable optional WebSocket functionality.

Attack Path

  1. A user follows the WebSocket setup instructions.
  2. pip or uv resolves the latest package release available from the configured package index.
  3. A compromised package index, compromised future release, or maliciously altered local mirror supplies unsafe package code.
  4. The pack ...[truncated 592 chars]
Remediation
View remediation

Remediation Suggestions

  1. Publish a reviewed compatible version range for websockets.
  2. Prefer a lock file or hash-pinned requirements file for reproducible installation.
  3. Provide a command such as python3 -m pip install --require-hashes -r requirements-websocket.txt.
  4. Document the expected package index and discourage untrusted mirrors.
  5. Add automated dependency vulnerability scanning and periodically update the reviewed pin.
  6. Keep WebSocket support optional and avoid installing packages automatically at runtime.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
Findings (30)

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · CONFIG.md (reported line 98)May include surrounding context.

Setup:

bash
python3 scripts/config_loader.py init --local
# Edit skills/aria2-json-rpc/config.json

Method 3: Environment Variables

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description presents a broad aria2 management skill capable of interacting with the download manager, querying status, and controlling tasks through natural language commands. In contrast, this code chunk is narrowly scoped to real-time monitoring of aria2 download events via WebSocket. It registers callbacks for events like start, pause, stop, complete, and error, waits for a specified duration, and prints a monitoring summary. It does not expose command handling, execute management operations, or provide a general-purpose aria2 control interface. While monitoring downloads is related to the declared domain, the primary purpose and implemented capabilities in this chunk are materially narrower and different from the declared skill behavior.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · references/troubleshooting.md (reported line 500)May include surrounding context.

bash
# Bypass skill scripts to test aria2 itself
curl -X POST http://localhost:6800/jsonrpc \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · CONFIG.md (reported line 187)May include surrounding context.

  • Check which file exists:
    bash
    ls -la skills/aria2-json-rpc/config.json
    ls -la ~/.config/aria2-skill/config.json
    

Invalid JSON

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

  1. File permissions:

    bash
    chmod 600 ~/.config/aria2-skill/config.json
    
  2. Use HTTPS for remote connections:

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill directs an agent to use shell, network, file read/write, and environment-backed configuration, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization gap: a host may permit broader execution than users expect, and an agent could be induced to perform networked download-management actions or write config files without clear policy boundaries.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation text is broad enough that an agent may invoke this skill in generic contexts involving downloads, torrent operations, or aria2-related phrasing, increasing the chance of unintended execution. Because the skill can trigger shell commands, network calls, and config file operations, overbroad activation raises the risk of accidental or policy-inappropriate actions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
85% confidence
Finding

Referencing npx skills without a pinned version introduces supply-chain risk because future installs or updates may fetch a changed package or dependency tree. If a compromised or breaking release is published, users updating the skill could execute unreviewed code or receive altered behavior.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
85% confidence
Finding

This is the same unpinned npx skills update path repeated elsewhere in the file, so the same supply-chain risk applies independently at this location. Users following the instruction may unknowingly fetch and execute a different package version than the one reviewed with this skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill advertises torrent-adding capability without warning that torrent use exposes the user's IP to peers, may consume significant bandwidth/storage, and can trigger legal or policy issues depending on content. For a natural-language-driven agent, omission of these cautions can lead to risky actions being taken without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The guide documents destructive operations such as removing active downloads and purging download results without instructing the agent to obtain explicit user confirmation or warn about irreversible effects. In an agentic context, this increases the chance of unintended data loss or disruption from ambiguous prompts or automation mistakes.

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 · references/execution-guide.md (reported line 189)May include surrounding context.

  1. Try with curl:
    bash
    curl -X POST http://localhost:6800/jsonrpc \
      -d '{"jsonrpc":"2.0","id":"test","method":"aria2.getVersion","params":[]}'
    

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 · references/troubleshooting.md (reported line 99)May include surrounding context.

  1. Try with curl:
    bash
    curl -X POST http://localhost:6800/jsonrpc \
      -d '{"jsonrpc":"2.0","id":"test","method":"aria2.getVersion","params":[]}'
    

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The markdown instructs the user to run killall aria2c and restart the daemon, which can interrupt in-progress downloads and alter system state. There is no nearby warning or disclosure that this action is disruptive or should only be used with caution.

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 · references/troubleshooting.md (reported line 500)May include surrounding context.

bash
# Bypass skill scripts to test aria2 itself
curl -X POST http://localhost:6800/jsonrpc \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The mapper exposes destructive operations like remove/delete/cancel directly from natural-language input without any built-in confirmation, safety gating, or distinction between read-only and state-changing actions. In an agent setting, this increases the chance that an ambiguous, mistaken, or prompt-injected instruction triggers deletion or cancellation of downloads, especially because the skill is specifically designed to execute management actions against aria2.

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 · scripts/config_loader.py (reported line 183)May include surrounding context.

python
except PermissionError:
            raise ConfigurationError(
                f"Permission denied reading config file: {path}\n"
                f"Please check file permissions: chmod 644 {path}"
            )
        except Exception as e:
            raise ConfigurationError(f"Error reading config file: {e}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The test_connection() path performs a real outbound HTTP/HTTPS request to a host, port, and optional path fully derived from configuration, and it may include the RPC secret as a token in the JSON-RPC params. In a skill context, this can trigger unintended network access to arbitrary internal or external endpoints and disclose sensitive configuration-derived credentials to the target service without an explicit warning or confirmation step.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · scripts/config_loader.py (reported line 293)May include surrounding context.

python
path = self.config.get("path") or ""
        url = f"{protocol}://{self.config['host']}:{self.config['port']}{path}"

        # Create a simple test request (aria2.getVersion)
        request_data = {
            "jsonrpc": "2.0",
            "id": "test-connection",

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/dependency_check.py (reported line 42)May include surrounding context.

python
for module in required_modules:
        try:
            __import__(module)
        except ImportError:
            missing_modules.append(module)

Static analysis

No suspicious patterns detected.