Back to skill

Security audit

easyclaw

Security checks for vulnerabilities and agentic risk

Overview

This EasyClaw trading skill is mostly transparent about what it does, but it includes high-impact live trading automation and broad account-control commands that need careful review before use.

Install only if you intend to grant this skill live trading authority. Use devnet or dry-run first, set a finite --max-orders limit, avoid arbitrary API/WS endpoints, keep API tokens scoped and separate, and review backend control commands before letting an agent invoke them. Treat wallet paths and strategy files saved by onboarding as sensitive local configuration.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/realtime-agent.js:428
Finding
Unauthenticated WebSocket Signals Can Trigger Real Financial Transactions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/realtime-agent.js:428-460`, with unsafe execution defaults at `scripts/realtime-agent.js:556-562` **Vulnerability Type**: Unauthenticated remote trade instruction handling **Risk Level**: High ### Vulnerable Code ```js function connectWebsocket(config, state, userMargin) { if (state.stopRequested) { return; } const endpoint = wsUrl(); const socket = new WebSocket(endpoint); state.socket = socket; let openedAt = 0; socket.on("open", () => { openedAt = Date.now(); state.reconnectAttempts = 0; console.log(`[info] websocket connected: ${endpoint}`); socket.send( JSON.stringify({ type: "subscribe", channel: config.channel }) ); }); socket.on("message", (raw) => { let envelope; try { envelope = JSON.parse(String(raw)); } catch (_err) { return; } const signals = signalItemsFromEnvelope(envelope); for (const signal of signals) { const signalAgent = String(signal.agent_name || "").trim(); const side = normalizeSignalSide(signal.side); const confidence = toNumber(signal.confidence, 0); const ts = Math.floor(toNumber(signal.ts, Math.floor(Date.now() / 1000))); if (!side) { continue; } if (config.agentNameFilter && signalAgent !== config.agentNameFilter) { continue; } if (confidence < config.minConfidence) { continue; } enqueueSignalExecution(signal, side, confidence, ts, config, state, userMargin); } }); ``` The execution branch places a real order unless dry-run mode was explicitly enabled: ```js if (config.dryRun) { console.log(`[dry-run] node scripts/order-execute.js ${orderArgs.join(" ")}`); } else { const result = await executeOrder(orderArgs); if (result.stdout.trim()) { process.stdout.write(result.stdout); } if (result.stderr.trim()) { process.stderr.write(result.stderr); } } ...[truncated 4071 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require authenticated WebSocket sessions before permitting trading signals. 2. Require every signal to have a cryptographic signature from an explicitly trusted signer. 3. Bind the signature to all security-relevant fields, including: - Channel - Signal ID - Agent ID - Market ID - Side - Confidence - Timestamp and expiration time - Intended wallet or trading session 4. Reject signals with missing, stale, or excessively future-dated timestamps. 5. Persist or maintain bounded replay protection using a unique signed signal ID rather than attacker-controlled display fields. 6. Verify that the envelope channel exactly matches the configured subscription. 7. Use immutable agent identifiers rather than self-asserted agent names. 8. Reject `ws://` for all non-loopback destinations. 9. Change direct autotrade to default to dry-run mode. Require an explicit `--live` option for real orders. 10. Set a finite default maximum order count and enforce cumulative notional, deposit, position, and loss limits locally. 11. Require explicit confirmation of market, margin, endpoint, trusted signer, and risk limits before starting a live autonomous session. 12. Consider requiring per-order confirmation unless an independently authenticated and time-bounded live-trading session has been established. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/backend-common.js:12
Finding
Bearer Tokens Can Be Sent to Arbitrary or Plaintext API Endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backend-common.js:12-18`, `scripts/backend-common.js:78-85`, and `scripts/backend-common.js:102-107` **Vulnerability Type**: Sensitive credential disclosure through insufficient endpoint validation **Risk Level**: Medium ### Vulnerable Code The API destination is entirely environment-controlled and permits plaintext HTTP: ```js function apiBaseUrl() { const raw = process.env.EASYCLAW_API_BASE_URL || process.env.API_BASE_URL || "http://127.0.0.1:8080"; return String(raw).trim().replace(/\/$/, ""); } ``` The token is attached whenever it is present, including for calls that do not require authentication: ```js const headers = { Accept: "application/json" }; const resolvedToken = authToken(token); if (resolvedToken) { headers.Authorization = `Bearer ${resolvedToken}`; } else if (requireAuth) { throw new Error( "Missing API auth token. Set EASYCLAW_API_TOKEN or pass --token." ); } ``` The request is then transmitted to the configured endpoint without enforcing HTTPS or an approved origin: ```js let response; try { response = await fetch(endpoint.toString(), { method, headers, body: payload, signal: controller.signal }); } finally { clearTimeout(timer); } ``` ### Technical Analysis `apiBaseUrl()` accepts any URL supplied through `EASYCLAW_API_BASE_URL` or `API_BASE_URL`. There is no validation that: - The scheme is HTTPS. - A plaintext endpoint is an exact loopback address. - The hostname belongs to an approved EasyClaw deployment. - The token audience matches the destination. - The destination changed from the expected production origin. When any supported API token is configured, `apiRequest()` automatically adds it to every request rather than only to operations marked `requireAuth`. This includes public health, market-data, and status requests. Therefore, invoking an otherwise harmless command can disclose the credential if the API base UR ...[truncated 1844 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require HTTPS for all non-loopback API destinations. 2. Permit plaintext HTTP only for exact loopback addresses under an explicit development-mode setting. 3. Validate the API origin against a configured allowlist before attaching credentials. 4. Default the approved production origin to `https://api.easyclaw.trade`. 5. Require an explicit confirmation or configuration flag before using a different authenticated origin. 6. Attach the bearer token only when `requireAuth` is true or when a specific endpoint is explicitly declared authenticated. 7. Use separate clients for public and authenticated API operations. 8. Use short-lived, audience-bound, narrowly scoped access tokens. 9. Ensure the backend validates token audience, issuer, expiration, and operation-specific scope. 10. Avoid broad alias variables such as `API_TOKEN` where unrelated applications could unintentionally supply credentials. 11. Redact credentials from all errors and diagnostic output. 12. Add automated tests confirming that: - Public requests contain no authorization header. - Plaintext non-loopback endpoints are rejected. - Unapproved origins never receive an authorization header. ]]>
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (47)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented websocket watch capability allows subscription to arbitrary channels and generic event monitoring, which exceeds the narrowly described balance/order functionality. In this context, undocumented event-stream monitoring can expose sensitive backend data flows or be repurposed as a trigger surface for automated actions, making the understated capability risky.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented websocket watch capability allows subscription to arbitrary channels and generic event monitoring, which exceeds the narrowly described balance/order functionality. In this context, undocumented event-stream monitoring can expose sensitive backend data flows or be repurposed as a trigger surface for automated actions, making the understated capability risky.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The documented websocket watch capability allows subscription to arbitrary channels and generic event monitoring, which exceeds the narrowly described balance/order functionality. In this context, undocumented event-stream monitoring can expose sensitive backend data flows or be repurposed as a trigger surface for automated actions, making the understated capability risky.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The documented websocket watch capability allows subscription to arbitrary channels and generic event monitoring, which exceeds the narrowly described balance/order functionality. In this context, undocumented event-stream monitoring can expose sensitive backend data flows or be repurposed as a trigger surface for automated actions, making the understated capability risky.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented websocket watch capability allows subscription to arbitrary channels and generic event monitoring, which exceeds the narrowly described balance/order functionality. In this context, undocumented event-stream monitoring can expose sensitive backend data flows or be repurposed as a trigger surface for automated actions, making the understated capability risky.

Ae1

High
Category
analysis-evasion
Content
- Backend endpoint source: `EASYCLAW_API_BASE_URL` / `EASYCLAW_WS_URL` (or alias vars in `backend-common.js`).
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- Backend endpoint source: `EASYCLAW_API_BASE_URL` / `EASYCLAW_WS_URL` (or alias vars in `backend-common.js`).
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- `scripts/backend.js`: backend REST API query helper
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- `scripts/realtime-agent.js`: signal-driven auto-order loop
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- `scripts/onboard.js`: interactive onboarding flow (wallet selection, registration wait, strategy capture, autotrade kickoff)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Known Vulnerable Dependency: bigint-buffer==1.1.5 — 1 advisory(ies): CVE-2025-3194 (bigint-buffer Vulnerable to Buffer Overflow via toBigIntLE() Function)

High
Category
Supply Chain
Confidence
92% confidence
Finding
The lockfile includes bigint-buffer 1.1.5, which is flagged for a buffer overflow in toBigIntLE(). Even though package-lock.json is not executable code itself, pinning a known vulnerable version means the skill will install and use that version transitively, and malformed inputs reaching the vulnerable path could crash the process or potentially enable memory corruption in environments where the native path is exercised.

Known Vulnerable Dependency: ws==7.5.10 — 1 advisory(ies): CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
90% confidence
Finding
The dependency tree contains ws 7.5.10 under jayson, and that version is reported vulnerable to memory-exhaustion denial of service from fragmented websocket traffic. In a DEX skill that may maintain network connections or process remote data, a websocket DoS can degrade availability and interrupt trading or balance checks.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
94% confidence
Finding
The top-level ws 8.19.0 is flagged for both uninitialized memory disclosure and memory-exhaustion denial of service. In a user-facing trading skill that may connect to Solana/EasyClaw websocket endpoints, these issues are more concerning because persistent network connectivity is core functionality, so exploitation could expose process memory or disrupt order submission and balance-monitoring availability.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
97% confidence
Finding
The analysis indicates resolution to ws 8.19.0, which is affected by memory disclosure and denial-of-service advisories. Because this skill includes websocket-related scripts and likely maintains live connections for market data or automation, an attacker or malicious endpoint could potentially crash the process or expose memory contents during network handling.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The documentation exposes capabilities that materially exceed the declared scope of the skill, including backend administration, strategy/session management, WebSocket control paths, autotrading, and onboarding flows. This is dangerous because downstream agents may select and trust the skill for limited order/balance tasks while actually gaining instructions for much broader and more sensitive actions, increasing the chance of unauthorized trading, control-plane misuse, or destructive operational actions.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The backend command set includes authenticated controls for agent creation, session start/stop, strategy publication, risk changes, and kill-switch operations, all of which exceed the stated purpose of submitting user orders and checking balances. These capabilities could be misused by an agent or operator to alter live trading behavior, disable operations, or modify account-level automation under the guise of a limited-scope skill.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The autotrade and onboarding sections describe automation that can directly lead to live order execution and persistent strategy-driven trading, which goes far beyond a simple user-facing order/balance helper. In skill ecosystems, understated autonomous trading behavior is particularly risky because an agent may invoke it without the user understanding that funds can be committed continuously after initial setup.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The script exposes a much broader administrative surface than the stated skill purpose of submitting EasyClaw orders and checking balances. It includes agent creation, strategy creation/publishing, owner rebinding, session lifecycle management, and auth flows, which materially expand what an agent can do if this skill is invoked or delegated unexpectedly.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The presence of risk-administration and kill-switch capabilities is high impact because these operations can alter safety controls or halt multiple agents, yet they are bundled into a skill described as a DEX trading helper. In an agent setting, overbroad access like this can be triggered by prompt confusion, misuse, or malicious delegation, causing account-wide operational disruption.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The `backend <command> [options...]` interface exposes a generic pass-through to `scripts/backend.js`, enabling callers to invoke arbitrary backend subcommands outside the narrow manifest scope. In a trading/wallet environment, this is dangerous because it can grant access to sensitive state or privileged operations not anticipated by users or higher-level policy.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The wrapper advertises an `autotrade` capability that can initiate autonomous trading behavior beyond the stated purpose of user-facing order and balance actions. In a financial skill context, autonomous execution is especially dangerous because it can place orders repeatedly or based on streaming inputs without granular user intent for each trade.

Credential Access

High
Category
Privilege Escalation
Content
const { parseArgs } = require("./common");

const SKILL_DIR = path.join(__dirname, "..");
const ENV_PATH = path.join(SKILL_DIR, ".env");
const STRATEGY_DIR = path.join(SKILL_DIR, "state", "strategies");

function usage() {
Confidence
84% confidence
Finding
The script reads and writes a local `.env` file and persists `KEYPAIR_PATH`/`ANCHOR_WALLET`, effectively enumerating and storing references to sensitive wallet credentials. In this context, that increases the attack surface around private key material because the skill scans for wallet locations, records them in project state, and reuses them for automated trading flows.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares extensive environment and network dependencies, including wallet paths and API tokens, but does not define an explicit tool scope such as permissions or allowed-tools. This creates an authorization gap where an agent may invoke networked or credentialed operations without clear policy boundaries, increasing the risk of unintended order placement, data exfiltration, or unsafe runtime behavior.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The agent-facing interface advertises capabilities materially broader than the stated skill scope, including authenticated control-plane actions such as agent/strategy management, risk controls, kill-switch operations, and realtime monitoring. This kind of scope inflation is dangerous because downstream agents may rely on the interface text as authority and invoke sensitive actions that were not clearly declared, reviewed, or constrained by the manifest.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The package exposes scripts such as backend, watch, autotrade, and onboard that go beyond the stated user-facing order and balance functionality. In a security review, this capability mismatch increases attack surface and may enable unexpected network connectivity, automation, or account lifecycle actions that users and integrators do not anticipate.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/onboard.js:84

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/realtime-agent.js:177