Back to skill

Security audit

Funding Rate Trader

Security checks for vulnerabilities and agentic risk

Overview

This skill can automatically place leveraged Binance Futures trades using local API keys, but its safeguards and disclosures are not adequate for that level of financial authority.

Review this carefully before installing. Use only restricted Binance API keys, avoid broad withdrawal permissions, prefer testnet or dry-run changes before live trading, and do not run the trader command unless you are prepared for immediate leveraged futures exposure and possible loss.

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
trader.js:86
Finding

Leveraged Position Can Remain Open Without Protective Orders

Content
View full analysis

Vulnerability Details

File Location: trader.js, lines 86-114
Vulnerability Type: Failure to safely handle partial trade execution
Risk Level: High

Vulnerable Code

js
// 开仓
const size = Math.min(available * 0.9, 100);
await exchange.setLeverage(CONFIG.LEVERAGE, best.symbol + '/USDT:USDT');

const qty = (size * CONFIG.LEVERAGE) / best.price;
await exchange.createOrder(best.symbol + '/USDT:USDT', 'market', 'buy', qty, null, {
  positionSide: 'LONG'
});
console.log('\n✅ 开仓:', qty.toFixed(4), best.symbol, '@', best.price);

// 等待
await new Promise(r => setTimeout(r, 1500));

// 设置止损止盈
const positions = await exchange.fetchPositions([best.symbol + '/USDT:USDT']);
const pos = positions.find(p => p.contracts > 0);

if (pos) {
  const stopLoss = best.price * (1 - CONFIG.STOP_LOSS);
  const takeProfit = best.price * (1 + CONFIG.TAKE_PROFIT);

  await exchange.createOrder(best.symbol + '/USDT:USDT', 'STOP_MARKET', 'sell', pos.contracts, null, {
    positionSide: 'LONG',
    triggerPrice: stopLoss
  });

  await exchange.createOrder(best.symbol + '/USDT:USDT', 'TAKE_PROFIT_MARKET', 'sell', pos.contracts, null, {
    positionSide: 'LONG',
    triggerPrice: takeProfit
  });
}

Technical Analysis

The script opens a market position at 20× leverage before submitting either protective exit order. It then deliberately waits 1.5 seconds, requests position information, and submits the stop-loss and take-profit as separate API operations.

These operations are not atomic. The entry can succeed while any subsequent operation fails because of process termination, network interruption, exchange timeout, rate limiting, invalid order parameters, stale position information, or an API rejection. The pos lookup can also fail to identify the newly opened position, in which case no protective orders are created.

If the first protective order succeeds but the second fails, the position is ...[truncated 1664 chars]

Remediation
View remediation

Remediation Suggestions

  • Treat entry and protection as a stateful transaction with explicit recovery behavior.
  • Validate symbol precision, quantity, position mode, trigger prices, and supported order parameters before opening the position.
  • Remove the unconditional 1.5-second exposure window and submit protection immediately after confirming the executed entry price and quantity.
  • Confirm that both protective orders were accepted and persist their order IDs.
  • If either protective order fails, cancel any successfully submitted sibling order and immediately close the actual remaining position with a reduce-only market order.
  • Add bounded retries with backoff for transient position-query and order-submission failures.
  • Re-fetch the exchange position after every failure rather than relying on local assumptions.
  • Install signal and shutdown handlers that attempt safe reconciliation without assuming that a local exception means the exchange operation failed.
  • On startup, reconcile existing positions and open orders so that a previous crash cannot leave exposure unmanaged.
  • Use the actual average entry price returned by the exchange rather than the earlier ticker price when calculating protective triggers.

T09 · Insecure Skill Coding Practices

Error
Location
trader.js:101
Finding

Conditional Exit Orders Lack Explicit Position-Reduction Safeguards

Content
View full analysis

Vulnerability Details

File Location: trader.js, lines 101-113
Vulnerability Type: Unsafe conditional exit-order construction
Risk Level: High

Vulnerable Code

js
await exchange.createOrder(best.symbol + '/USDT:USDT', 'STOP_MARKET', 'sell', pos.contracts, null, {
  positionSide: 'LONG',
  triggerPrice: stopLoss
});

await exchange.createOrder(best.symbol + '/USDT:USDT', 'TAKE_PROFIT_MARKET', 'sell', pos.contracts, null, {
  positionSide: 'LONG',
  triggerPrice: takeProfit
});

console.log('✅ 止损:', stopLoss.toFixed(4), '(-' + (CONFIG.STOP_LOSS * 100) + '%)');
console.log('✅ 止盈:', takeProfit.toFixed(4), '(+' + (CONFIG.TAKE_PROFIT * 100) + '%)');

Technical Analysis

Both conditional sell orders use the entire observed contract quantity, but neither order explicitly uses reduceOnly or closePosition semantics. The code also does not implement one-cancels-the-other behavior or cancel the remaining conditional order after the position is closed.

Consequently, the orders are not demonstrably constrained to reducing the position that existed when they were submitted. Actual behavior depends on the Binance account position mode, Binance Futures order rules, and the version of CCXT in use. A stale sibling order may remain active after the other exit executes. It may subsequently be rejected, interfere with later trades, or create unintended exposure where the exchange and account mode permit it.

The position quantity is captured once and is not reconciled before either conditional order executes. Manual reductions, liquidation, other bots, or later account activity can therefore make the submitted quantity inconsistent with the current position.

Attack Path

  1. The script opens a long position and submits separate stop-loss and take-profit sell orders for the observed contract count.
  2. One conditional order triggers and closes or reduces the long position.
  3. The script does not ca ...[truncated 1127 chars]
Remediation
View remediation

Remediation Suggestions

  • Use the Binance/CCXT-supported reduceOnly or closePosition parameter for every protective exit, as appropriate for the configured account mode.
  • Explicitly detect and validate whether the account uses one-way or hedge mode before trading.
  • Implement one-cancels-the-other behavior: after one exit fills, immediately cancel its sibling and verify the remaining position.
  • Persist both conditional-order IDs and monitor their status rather than terminating immediately after submission.
  • Before acting on an exit, reconcile the current position quantity and prevent an order from exceeding the remaining exposure.
  • Cancel obsolete protective orders before opening a new position in the same symbol.
  • Add integration tests against the Binance test environment for both one-way and hedge modes.
  • Pin a tested CCXT version and verify the exact unified parameters translated to Binance Futures order fields.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A skill advertised as funding-rate arbitrage but actually performing directional leveraged trading materially changes the risk profile for users, especially when coupled with secret access and automatic execution claims. In this context, misleading users about both strategy type and credential requirements can lead to unexpected financial loss and unsafe automated trading behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill advertised as funding-rate arbitrage but actually performing directional leveraged trading materially changes the risk profile for users, especially when coupled with secret access and automatic execution claims. In this context, misleading users about both strategy type and credential requirements can lead to unexpected financial loss and unsafe automated trading behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

A skill advertised as funding-rate arbitrage but actually performing directional leveraged trading materially changes the risk profile for users, especially when coupled with secret access and automatic execution claims. In this context, misleading users about both strategy type and credential requirements can lead to unexpected financial loss and unsafe automated trading behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

A skill advertised as funding-rate arbitrage but actually performing directional leveraged trading materially changes the risk profile for users, especially when coupled with secret access and automatic execution claims. In this context, misleading users about both strategy type and credential requirements can lead to unexpected financial loss and unsafe automated trading behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script places real leveraged futures market orders and then configures stop-loss/take-profit automatically, using locally stored Binance API credentials, without any user confirmation, dry-run mode, or explicit acknowledgment of trading risk. In the context of an agent skill, this is dangerous because a single execution can immediately open a 20x leveraged position with substantial loss potential from slippage, bad market data, logic errors, or accidental invocation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill declares no explicit tool scope or permissions while the documented workflow involves reading local secrets from ~/.openclaw/secrets/binance.json, which implies access to sensitive local environment/resources without transparent declaration. In an agent setting, undeclared secret access increases the risk of overbroad execution and credential misuse, even if the stated purpose is trading-related rather than overtly malicious.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README promotes automated 20x leveraged trading and highly optimistic returns without prominent warnings about credential exposure, live-order execution, liquidation risk, or loss amplification. In a trading skill, understated warnings are particularly dangerous because users may connect real exchange accounts and enable automation without understanding the consequences.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
76% confidence
Finding

Storing long-lived Binance API credentials in a fixed session-persistent local file under ~/.openclaw/secrets/binance.json creates a durable secret target for any other local process or overly broad skill that can access the same path. Persistence is not inherently malicious, but without stronger guidance on permissions, encryption, or least-privilege API keys, it raises the blast radius of compromise.

Content

Scanner excerpt · SKILL.md (reported line 35)May include surrounding context.

Configuration

Create ~/.openclaw/secrets/binance.json:

json
{
  "apiKey": "your-api-key",

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a skill for scanning negative funding rates and auto-trading with stop-loss/take-profit. This file instead reads Binance credentials, fetches live account positions, and prints unrealized PnL, which is account monitoring behavior not mentioned in the stated skill description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script reads Binance API credentials from a fixed local secrets path under the user's home directory without any runtime consent or clear need tied to simple market scanning. Accessing local secret material is sensitive because it expands the skill's privileges from public-data analysis to account-linked access, and a user may not expect that from the described capability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code silently loads exchange API credentials and initializes an authenticated Binance futures client without warning the user. In the context of a skill advertised as not needing API keys for scanning, undisclosed credential use is particularly dangerous because it can surprise users into granting account access they did not intend.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script performs authenticated network calls to Binance to fetch positions with no disclosure that account data will be queried. Because this skill is framed as a funding-rate arbitrage scanner, hidden account-access API usage is more dangerous than in a clearly documented portfolio-monitoring tool: it violates user expectations and unnecessarily exposes private account information to the skill's runtime.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script claims scanning does not require an API key, but it unconditionally reads Binance credentials from a local secrets file before doing a read-only funding-rate scan. This unnecessarily accesses sensitive material and expands the blast radius: any user running the scanner must expose local API credentials even though the current functionality does not need them.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file only fetches and prints funding-rate opportunities, yet it reads local secret material from ~/.openclaw/secrets/binance.json. Even without obvious exfiltration in this snippet, unnecessary secret access is dangerous because it violates least privilege and makes the scanner a high-value target for future abuse or accidental leakage through logs, crashes, or later code changes.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This markdown file describes the skill's purpose in broad terms but does not specify how or when the skill should be invoked, nor does it provide narrow trigger phrases or exclusion conditions. For a skill manifest/README, this can make activation criteria ambiguous and increase the chance of unintended invocation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file contains user-facing descriptive text in Chinese ('扫描负费率机会', '无需 API Key,任何人都可以使用') without indicating that the skill is Chinese-specific or offering an alternative language. This can violate language/locale policy when a skill implicitly forces a language without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file performs HTTPS requests to Binance APIs, which transmits usage metadata such as the user's IP address to a third party. Although the script title implies scanning funding rates, there is no explicit warning, prompt, or disclosure in code comments or console output that external network access will occur.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

User-visible strings throughout the script are written in Chinese, and the file provides no option to select another language or opt in to this locale. That can violate language/locale policy when a skill imposes a specific language by default.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.