T05 · Unauthorized Access and Privilege Escalation
- Location
packages/plugins/openclaw-openmm/src/index.ts:133- Finding
State-Changing Trading Tools Do Not Enforce User Approval or Authorization
- Content
View full analysis
Vulnerability Details
File Location:
packages/plugins/openclaw-openmm/src/index.ts, lines 133-200
Vulnerability Type: Missing authorization and confirmation enforcement for financial operations
Risk Level: HighVulnerable Code
typescript // Create order (optional — requires explicit approval) api.registerTool( { name: "openmm_create_order", description: "Place a limit or market order. IMPORTANT: Always confirm with the user before executing.", parameters: Type.Object({ exchange: Type.String({ description: "Exchange id" }), symbol: Type.String({ description: "Trading pair, e.g. SNEK/USDT" }), side: Type.String({ description: "buy or sell" }), type: Type.String({ description: "limit or market" }), amount: Type.Number({ description: "Order amount in base currency" }), price: Type.Optional(Type.Number({ description: "Limit price (required for limit orders)" })), }), async execute( _id: string, params: { exchange: string; symbol: string; side: string; type: string; amount: number; price?: number }, ) { const args = [ "orders", "create", "--exchange", params.exchange, "--symbol", params.symbol, "--side", params.side, "--type", params.type, "--amount", String(params.amount), ]; if (params.price != null) args.push("--price", String(params.price)); return text(await openmm(args)); }, }, { optional: true }, ); // Cancel order (optional) api.registerTool( { name: "openmm_cancel_order", description: "Cancel a specific order by ID.", parameters: Type.Object({ exchange: Type.String({ description: "Exchange id" }), orderId: Type.String({ description: "Order ID to cancel" }), symbol: Type.String({ descript ...[truncated 4014 chars]- Remediation
View remediation
Remediation Suggestions
- Enforce authorization in code for every state-changing tool. Validate the authenticated OpenClaw principal and restrict access to an explicit allowlist of users, channels, and roles.
- Implement a two-phase transaction flow:
- First generate a normalized order or cancellation preview.
- Return a short-lived approval identifier bound to the user, exchange, symbol, side, type, amount, price, and expiration time.
- Require a second authenticated call containing that identifier before execution.
- Apply
requireAuthor the equivalent framework authorization control to agent tools, not only chat commands. - Require fresh confirmation for any changed parameter. Do not accept a generic earlier statement such as “you may trade” as approval for later transactions.
- Enforce server-side limits for permitted exchanges, symbols, order sizes, daily notional value, price deviation, and cancellation scope.
- Do not allow
cancel-allwithout an explicit symbol unless the user separately approves an account-wide cancellation. - Record immutable audit events containing the authenticated actor, originating channel, approved parameters, tool invocation ID, CLI result, and exchange order IDs. Redact all credentials.
- Keep withdrawal permissions disabled and use dedicated API keys with the minimum read/trade permissions and IP restrictions.
- Add automated tests proving that direct calls without a valid, unexpired approval token are rejected.
