Back to skill

Security audit

Aidex

Security checks for vulnerabilities and agentic risk

Overview

This Ethereum swapping skill is transparent about using a local wallet key, but its transaction checks leave users exposed to API-controlled bad trades, excess approvals, or high gas fees.

Review this carefully before installing. Use only a dedicated wallet with limited funds, avoid storing a high-value private key for agent use, verify final swap terms and fees independently, and be aware that token approvals may grant the router spending authority beyond the immediate swap.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/swap.js:242
Finding

API-Controlled ERC-20 Approval Amount Is Not Bounded to the Requested Swap

Content
View full analysis
hex chars 34..74. const spender = "0x" + data.slice(34, 74); if (spender !== ROUTER_ADDRESS) fail(); // USDT-style reset pattern: a pair of approves where the first sets allowance // to 0 (required by tokens that disallow direct allowance change) and the // second sets the new non-zero allowance. A solo approve must be non-zero. const amount = BigInt("0x" + data.slice(74, 138)); if (isFirstOfPair) { if (amount !== 0n) fail(); } else { if (amount === 0n) fail(); } if (BigInt(tx.value) !== 0n) fail(); } ``` ### Technical Analysis The Skill correctly limits the approval spender to the hardcoded AIDEX router, but it does not limit the allowance amount. For a normal approval, any nonzero value is accepted, including the maximum `uint256` value. The API constructs the unsigned approval transaction. Consequently, a compromised or faulty API can return an unlimited approval even when the user requested only a small swap. This approval passes local validation because the validator checks only that the amount is nonzero. The resulting permission exceeds the minimum authority necessary to execute the requested swap. An exact or narrowly bounded allowance would be sufficient. ### Attack Path 1. A user requests a swap of a limited amount of an ERC-20 token. 2. The AIDEX API returns an approval transaction calling: `approve(ROUTER_ADDRESS, 2^256 - 1)`. 3. ...[truncated 979 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/swap.js:221
Finding

User-Confirmed Quote Is Not Bound to the Transaction That Is Signed

Content
View full analysis
--tokens ETH,USDC → show balances and allowance 5. swap.js --token-in ETH --token-out USDC --amount-in 0.5 → execute (approve + swap if needed) ``` ### Technical Analysis The user confirms the result returned by `rate.js`, but `swap.js` does not receive the confirmed `amountOut`, a user-approved minimum output, or a cryptographically bound quote identifier. Instead, `s ...[truncated 1771 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/swap.js:277
Finding

API-Controlled Gas Parameters Are Signed Without Local Fee Limits

Content
View full analysis
Remediation
View remediation
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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is a blockchain token swapping skill, but this code chunk merely reads package metadata from a local package.json file to obtain a version number. That behavior is a build/runtime metadata utility and does not implement or directly support any of the core user-facing capabilities described. Because the actual behavior in this chunk is materially unrelated to the declared swap functionality, this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The code is consistent with the core declared purpose of executing Ethereum swaps through AIDEX with client-side signing: it obtains swap transactions from an API, performs substantial local validation, signs locally, and sends the signed transactions. However, the declared description also claims capabilities to search tokens, check exchange rates, and view balances, none of which are implemented in this supplied code chunk. There is no evidence of unrelated triggers, extra sensitive resource access, or undeclared harmful behavior. The mismatch is therefore a scope/feature mismatch: the code chunk only covers swap execution, not the broader set of described features.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
81% confidence
Finding

The skill is designed around using a highly sensitive Ethereum private key via environment variable or keyring, and the metadata even identifies AIDEX_PRIVATE_KEY as the primary environment source. In a transaction-signing skill, any mechanism that normalizes secret provisioning and agent access materially raises the stakes: compromise of the runtime, logs, subprocess environment, or misconfiguration can lead directly to theft of wallet funds.

Content

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

md
6. **After a swap, always call swap-status.js** to verify the actual result and show it to the user.
7. **Private key not configured?** If no private key is available, present **all** configuration options: environment variable (via `openclaw config set`) **and** system keyring. Do not default to a single option — let the user choose.
8. **NEVER loop or auto-retry on errors.** If any transaction reverts or the API returns an error, stop the current operation and report to the user. Do not automatically retry. If the user wants to try again, they will say so.
9. **NEVER access the private key directly.** Do not read openclaw.json, .env files, or any other configuration files to extract the private key. Do not pass the private key as a command-line argument — command-line arguments are visible to all processes on the system. Passing the key this way is equivalent to leaking it to an attacker. The key is resolved from the AIDEX_PRIVATE_KEY environment variable or the system keyring. If neither source provides a valid key, inform the user and stop. No workarounds.
10. **While a transaction is mining**, you can show the user a link to track it: `https://etherscan.io/tx/{transactionHash}`. This applies to all transactions (swap, approve).
11. **Detect the user's environment.** When helping with private key setup, adapt your suggestions to the user's environment. If the user is running in a containerized or headless Linux environment (Docker, WSL, CI), lead with the environment variable approach (Option A) — do not mention the system keyring unless the user explicitly asks about alternatives. If asked, explain that the system keyring is available for desktop operating systems (Windows, macOS, Linux with a graphical session) but is not accessible from containers or headless environments. For desktop users, present all keyring options but highlight the one matching their OS first.
12. **Never ask the user about private key configuration proactively.** Do not ask "is your pri
...[truncated 25 chars]

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
85% confidence
Finding

Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Content

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

md
13. **Do not assume the private key is missing — check by running the script.** When the user asks for their balance, wallet address, or any operation that may require a private key, do not refuse preemptively. Run `account.js` — if the key is configured, you'll get the wallet address. If not, the script will return a clear error explaining what to set up. This is a read-only operation with no cost and no risk. Never tell the user "I can't do this" without actually trying first.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · package.json (reported line 14)May include surrounding context.

json
"ethers": "6.16.0"
  },
  "optionalDependencies": {
    "@napi-rs/keyring": "1.2.0"
  }
}

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/security.md (reported line 48)May include surrounding context.

md
"ethers": "6.16.0"
  },
  "optionalDependencies": {
    "@napi-rs/keyring": "1.2.0"
  }
}

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/lib/utils.js (reported line 209)May include surrounding context.

js
"ethers": "6.16.0"
  },
  "optionalDependencies": {
    "@napi-rs/keyring": "1.2.0"
  }
}

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/lib/utils.js (reported line 216)May include surrounding context.

js
"ethers": "6.16.0"
  },
  "optionalDependencies": {
    "@napi-rs/keyring": "1.2.0"
  }
}

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The manifest declares a user-invocable skill that needs environment access and network access, but it does not explicitly constrain or document those capabilities via a tool-scope/permissions field. In a wallet-trading context, unclear privilege boundaries increase the chance of overbroad execution and make it harder for reviewers or runtime policy engines to limit sensitive operations such as secret use and outbound requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The skill is marked user-invocable with a broad description and no clear trigger constraints. For a financial skill capable of signing and broadcasting Ethereum transactions, broad invocation increases the risk of accidental activation in contexts where the user intended only informational assistance, especially if an agent auto-selects skills from descriptions.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
9. **NEVER access the private key directly.** Do not read openclaw.json, .env files, or any other configuration files to extract the private key. Do not pass the private key as a command-line argument — command-line arguments are visible to all processes on the system. Passing the key this way is equivalent to leaking it to an attacker. The key is resolved from the AIDEX_PRIVATE_KEY environment variable or the system keyring. If neither source provides a valid key, inform the user and stop. No workarounds.
10. **While a transaction is mining**, you can show the user a link to track it: `https://etherscan.io/tx/{transactionHash}`. This applies to all transactions (swap, approve).
11. **Detect the user's environment.** When helping with private key setup, adapt your suggestions to the user's environment. If the user is running in a containerized or headless Linux environment (Docker, WSL, CI), lead with the environment variable approach (Option A) — do not mention the system keyring unless the user explicitly asks about alternatives. If asked, explain that the system keyring is available for desktop operating systems (Windows, macOS, Linux with a graphical session) but is not accessible from containers or headless environments. For desktop users, present all keyring options but highlight the one matching their OS first.
12. **Never ask the user about private key configuration proactively.** Do not ask "is your private key configured?" or offer to help with setup when the user first interacts with the skill. The user may not even know what a private key is. Simply run the requested operation — if the key is needed and not configured, the script will return a clear error, and only then should you explain what happened and how to set it up. For read-only operations (rate, tokens, balances), the key is not needed at all — do not mention it.
13. **Do not assume the private key is missing — check by running the script.** When the user asks for their balance, wallet address,
...[truncated 26 chars]

Behavior Manipulation

Medium
Category
Prompt Injection
Confidence
75% confidence
Finding

Subtle instructions detected that may alter agent decision-making or introduce hidden biases.

Content

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

md
10. **While a transaction is mining**, you can show the user a link to track it: `https://etherscan.io/tx/{transactionHash}`. This applies to all transactions (swap, approve).
11. **Detect the user's environment.** When helping with private key setup, adapt your suggestions to the user's environment. If the user is running in a containerized or headless Linux environment (Docker, WSL, CI), lead with the environment variable approach (Option A) — do not mention the system keyring unless the user explicitly asks about alternatives. If asked, explain that the system keyring is available for desktop operating systems (Windows, macOS, Linux with a graphical session) but is not accessible from containers or headless environments. For desktop users, present all keyring options but highlight the one matching their OS first.
12. **Never ask the user about private key configuration proactively.** Do not ask "is your private key configured?" or offer to help with setup when the user first interacts with the skill. The user may not even know what a private key is. Simply run the requested operation — if the key is needed and not configured, the script will return a clear error, and only then should you explain what happened and how to set it up. For read-only operations (rate, tokens, balances), the key is not needed at all — do not mention it.
13. **Do not assume the private key is missing — check by running the script.** When the user asks for their balance, wallet address, or any operation that may require a private key, do not refuse preemptively. Run `account.js` — if the key is configured, you'll get the wallet address. If not, the script will return a clear error explaining what to set up. This is a read-only operation with no cost and no risk. Never tell the user "I can't do this" without actually trying first.
14. **When asking for a wallet address, warn the user not to confuse it with a private key.** Both start with `0x`, but an address is 42 characters and is safe t
...[truncated 25 chars]

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The swap documentation describes a script that signs and submits approval and swap transactions, but it does not prominently warn that these actions move assets on-chain, may grant token spending approvals, and are generally irreversible once broadcast. In an agent setting, insufficient safety framing increases the risk of unintended or inadequately confirmed swaps, especially when users rely on the skill to automate high-value transactions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest describes an Ethereum token swap skill, but this token registry clearly includes many non-plain Ethereum token assets such as Ondo tokenized equities and ETFs (for example Apple, American Airlines, and other securities-like instruments), as well as wrapped representations of external-chain assets. That broadens the skill from Ethereum token swapping into discovery and potential handling of real-world-asset and cross-ecosystem instruments, which is not reflected in the manifest description.

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 · scripts/lib/api.js (reported line 7)May include surrounding context.

js
import { isAddress, isAmount, isHash, isHex, isNonEmptyString, isNumber } from "./utils.js";
import { SKILL_VERSION } from "./version.js";

const BASE_URL = "https://api.ai-dex.io/api/v1/agent";

const ERROR_CODE = {
  TEMPORARILY_UNAVAILABLE: 0,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest emphasizes Ethereum token swapping with client-side signing keeping the private key on the user's machine, but this utility file also implements direct secret retrieval from process environment and OS keyring storage. Accessing local credential stores is a sensitive capability that is not explicitly stated in the skill description and goes beyond ordinary normalization/helper logic.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function resolves a private key from an environment variable and then falls back to reading a secret from the system keyring. While the code comments describe the source priority, there is no user-facing confirmation, warning, or disclosure that sensitive credentials will be accessed during execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code sends fully signed transactions to sendSwap, which is a network operation involving highly sensitive transaction payloads. While the file has internal comments describing the flow, it does not include any user-facing disclosure, confirmation, or warning before transmitting the signed transactions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The natural-language configuration fixes the skill to Ethereum mainnet only, which is a locale/network constraint presented as mandatory rather than a user choice. Under the policy, forcing a specific language/locale-like setting without opt-in can be a violation unless clearly justified as region-specific; this file does not explicitly frame the restriction as a justified network-specific limitation in the policy sense.

Content

No source excerpt is available for this finding.