Back to skill

Security audit

AgentHub - 32 AI APIs via x402

Security checks for vulnerabilities and agentic risk

Overview

This paid API gateway is coherent in purpose, but it asks users to install an unpinned SDK, pass it a wallet private key, and run unsafe shell-script templates.

Review before installing. Use only a dedicated low-balance wallet, avoid secrets or sensitive business data in API inputs, and do not use the documented shell template as written. Prefer a pinned, reviewed SDK install and a safer static script that passes request data as JSON without shell interpolation.

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)

T08 · Insecure Dependencies

Error
Location
SKILL.md:50
Finding

Automatic Installation of an Unpinned Security-Critical npm Dependency

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 50-53; related installation instructions also appear at lines 23 and 306
Vulnerability Type: Unpinned third-party dependency and unsafe automatic installation
Risk Level: High

Vulnerable Code

bash
[ -f "$HOME/.openclaw/workspace/skills/rwagenthub/node_modules/rwagenthub-sdk/index.js" ] || \
  npm install --prefix "$HOME/.openclaw/workspace/skills/rwagenthub" rwagenthub-sdk --silent

The same package is manually installed without a version constraint at line 23:

bash
npm install --prefix ~/.openclaw/workspace/skills/rwagenthub rwagenthub-sdk

Technical Analysis

The Skill instructs the agent to install rwagenthub-sdk without an exact version, lockfile, or integrity hash. Consequently, npm resolves whichever package version is current at installation time. The automatic pre-call check makes dependency installation part of normal operation and uses --silent, reducing the visibility of installation warnings and lifecycle-script activity.

This dependency is security-critical because the Skill subsequently provides it with process.env.MCP_WALLET_PRIVATE_KEY. A compromised package release, compromised maintainer account, registry takeover, or malicious transitive dependency could execute code during npm installation or SDK initialization. npm lifecycle scripts may execute before the SDK is used, while malicious runtime code could directly read the wallet key.

The project contains no bundled SDK implementation or integrity metadata with which to verify the package behavior or the assertion that the private key remains local.

Attack Path

  1. An attacker compromises the npm package, its maintainer account, or one of its dependencies.
  2. The attacker publishes a malicious version while retaining the expected package name.
  3. The SDK installation check determines that the expected file is absent on a new or cleaned environment.

...[truncated 1066 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin the SDK to an exact, reviewed version rather than relying on npm's latest matching release.
  • Commit and enforce a lockfile containing resolved versions and integrity hashes.
  • Use npm ci against the reviewed lockfile instead of automatically resolving dependencies.
  • Verify package provenance, signatures, and registry integrity before installation.
  • Disable npm lifecycle scripts with --ignore-scripts unless they are demonstrably required and reviewed.
  • Remove automatic package installation from the API-call path. Require an explicit, user-approved setup phase.
  • Avoid --silent for security-sensitive installation so warnings and executed actions remain visible.
  • Vendor or independently audit the signing component because it handles a wallet private key.
  • Isolate the SDK in a restricted process with minimal filesystem and network access.
  • Use a dedicated low-balance wallet with narrowly limited token approvals, as already recommended by the documentation.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:66
Finding

Shell Command Injection Through an Unquoted Heredoc

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 66-74; the same construction is repeated at lines 287-294
Vulnerability Type: Shell command injection
Risk Level: High

Vulnerable Code

bash
cat > /tmp/agenthub-call.mjs << SCRIPT
import AgentHub from '$HOME/.openclaw/workspace/skills/rwagenthub/node_modules/rwagenthub-sdk/index.js';

const hub = new AgentHub({ privateKey: process.env.MCP_WALLET_PRIVATE_KEY });
const result = await hub.call('API_NAME', { ...inputs... });
console.log(JSON.stringify(result, null, 2));
SCRIPT

node /tmp/agenthub-call.mjs

Technical Analysis

The heredoc delimiter SCRIPT is not quoted. Shells therefore perform parameter expansion, command substitution, and arithmetic expansion on the heredoc body before writing it to /tmp/agenthub-call.mjs.

The documentation directs the agent to replace API_NAME and { ...inputs... } with request-specific values. Many supported APIs accept arbitrary or externally influenced strings, including search queries, URLs, email subjects and bodies, scraping prompts, and source code. If such a value is inserted directly into this template, shell syntax such as $(command) or backtick command substitution can execute locally while the temporary file is created.

JavaScript quoting does not prevent this issue because shell expansion happens before Node.js parses the generated JavaScript. A payload can therefore execute even if the resulting JavaScript is invalid.

Attack Path

  1. An attacker supplies or influences a value intended for an AgentHub API, such as a search query, URL, scraping prompt, email body, or code string.
  2. The value contains shell command-substitution syntax, for example a $(...) expression.
  3. The agent follows the documented template and interpolates the value into the unquoted heredoc.
  4. The shell expands the heredoc before cat writes the JavaScript file.
  5. The command inside the ...[truncated 1025 chars]
Remediation
View remediation

Remediation Suggestions

  • Quote the heredoc delimiter to disable shell expansion:
bash
cat > "$script_path" <<'SCRIPT'
// Static JavaScript only
SCRIPT
  • Do not interpolate API names or inputs into generated shell or JavaScript source.
  • Serialize request parameters using a real JSON encoder and store them in a securely created data file.
  • Pass only the data-file path to Node.js and parse the JSON from within the static script.
  • Alternatively, use standard input or a narrowly scoped environment variable with strict parsing and validation.
  • Validate API names against an explicit allowlist.
  • Apply type, length, and format validation to every API parameter.
  • Treat search text, URLs, prompts, email content, and code fields as untrusted input regardless of their apparent origin.
  • Add regression tests containing $(), backticks, quotes, newlines, and heredoc terminators to verify that inputs cannot trigger shell evaluation.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:66
Finding

Predictable Shared Temporary File Enables Symlink and Race Attacks

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 66-74; the same fixed path is reused at lines 287-294
Vulnerability Type: Unsafe temporary-file handling
Risk Level: Medium

Vulnerable Code

bash
cat > /tmp/agenthub-call.mjs << SCRIPT
import AgentHub from '$HOME/.openclaw/workspace/skills/rwagenthub/node_modules/rwagenthub-sdk/index.js';

const hub = new AgentHub({ privateKey: process.env.MCP_WALLET_PRIVATE_KEY });
const result = await hub.call('API_NAME', { ...inputs... });
console.log(JSON.stringify(result, null, 2));
SCRIPT

node /tmp/agenthub-call.mjs

Technical Analysis

The Skill writes executable JavaScript to the fixed path /tmp/agenthub-call.mjs. Shared temporary directories are generally writable by other local users and processes. The command neither creates the file exclusively nor verifies its ownership, type, permissions, or inode before execution.

If an attacker pre-creates this path as a symbolic link, the shell redirection may overwrite another file writable by the victim account. There is also a time-of-check/time-of-use window between writing and executing the file. An attacker able to manipulate the temporary path can replace the generated script after cat finishes but before Node.js opens it.

Concurrent legitimate calls also use the same path. One invocation may overwrite another invocation's script, causing request confusion, unintended paid calls, or execution of content associated with a different user request.

Attack Path

Symlink overwrite path:

  1. A local attacker predicts the documented fixed filename.
  2. The attacker creates /tmp/agenthub-call.mjs as a symbolic link to a file writable by the victim.
  3. The victim invokes the Skill.
  4. Shell redirection follows the symbolic link and truncates or overwrites the target file.
  5. Depending on the selected target, the attacker causes denial of service, configuration corruption, or ...[truncated 1010 chars]
Remediation
View remediation

Remediation Suggestions

  • Create a unique private temporary directory using mktemp -d.
  • Set a restrictive umask, such as 077, before creating scripts or request files.
  • Store the script inside the private directory and use fully quoted paths.
  • Install an exit trap that removes the temporary directory:
bash
umask 077
tmpdir="$(mktemp -d)" || exit 1
trap 'rm -rf -- "$tmpdir"' EXIT
script_path="$tmpdir/agenthub-call.mjs"
  • Create files exclusively and avoid following symbolic links where platform APIs permit.
  • Verify the file is a regular file owned by the current user before execution.
  • Prefer a maintained static script in the Skill directory rather than generating executable source in /tmp.
  • Pass per-call inputs as validated JSON through standard input or a private data file.
  • Ensure each concurrent invocation receives a separate directory and filename.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (3)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This skill is a gateway to many external APIs that can receive user queries, URLs, geolocation data, wallet addresses, and other inputs, but the documentation lacks a general disclosure that such data is transmitted off-device. That omission increases the risk of users unknowingly sharing sensitive information with third parties across multiple API categories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code_exec feature submits code to a remote execution service, but the skill text does not prominently disclose that the supplied code leaves the local environment. Users may include proprietary logic, credentials, sample data, or internal URLs in code snippets, resulting in sensitive data exposure to an external processor.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The email_send capability causes recipient addresses, subject lines, and message bodies to be transmitted to an external service, yet the skill does not clearly warn users about that data flow. This can lead to unintended disclosure of sensitive personal, business, or regulated information when users assume the tool is only acting locally.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.