Back to skill

Security audit

Crypto Wallets & Payments for AI Agents

Security checks for vulnerabilities and agentic risk

Overview

This skill is for crypto payments, but it asks agents to handle raw wallet private keys and run an unpinned external MCP server that can move real funds.

Review carefully before installing. Use only a dedicated low-value or testnet wallet, do not paste a primary wallet private key into an agent chat or shell history, pin and review the MCP server package before running it, and require explicit human review of every transfer, approval, swap amount, destination, chain, and fee.

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:16
Finding

Mutable npm Dependency Executes with Wallet Credentials

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 16-28
Vulnerability Type: Supply-chain exposure through an unpinned executable dependency
Risk Level: High

Vulnerable Code

bash
mcporter config add onlyswaps --command "npx -y @onlyswaps/mcp-server@latest stdio" --transport stdio
json
{
  "mcpServers": {
    "onlyswaps": {
      "command": "npx",
      "args": ["-y", "@onlyswaps/mcp-server@latest", "stdio"]
    }
  }
}

Technical Analysis

The configuration uses npx -y to download and execute the mutable latest release of @onlyswaps/mcp-server. The -y option suppresses interactive confirmation, while the @latest tag can resolve to different package contents at different times. No exact version, lockfile, integrity hash, or locally auditable implementation is supplied by the project.

The downloaded MCP server is subsequently expected to operate with a cryptocurrency wallet private key and exposes capabilities for token transfers, swaps, and token approvals. Consequently, compromise of the npm account, package publication pipeline, dependency graph, or a future package release could place attacker-controlled code in a process with access to wallet credentials and transaction authority.

Attack Path

  1. An attacker compromises the npm package, its maintainer account, publication pipeline, or a transitive dependency.
  2. The attacker publishes a malicious release under the package's latest tag.
  3. A user follows the documented setup command.
  4. npx -y retrieves and executes the malicious release without displaying an installation confirmation.
  5. The user invokes a wallet operation and supplies PRIVATE_KEY to the MCP server process.
  6. The malicious process reads or exfiltrates the key, alters transaction parameters, or submits unauthorized approvals and transfers.
  7. The attacker uses the acquired signing authority or approvals to steal wallet ass ...[truncated 405 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace @latest with an exact, reviewed package version.
  • Use a lockfile and verify package integrity hashes before execution.
  • Remove automatic -y installation from security-sensitive deployment instructions.
  • Vendor or publish the corresponding source code so credential handling and transaction construction can be audited.
  • Run the MCP server in a sandbox with restricted filesystem and network access.
  • Use a dedicated, low-value wallet rather than a primary wallet.
  • Require explicit review and confirmation of destination addresses, token amounts, spender approvals, fees, and chain IDs before signing.
  • Establish a controlled dependency-update process that requires code review and security testing before changing the pinned version.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:65
Finding

Raw Private Keys Are Requested and Stored in Plaintext

Content
View full analysis

Vulnerability Details

File Locations: SKILL.md, lines 40-41, 65-78, 109-125, and 151
Vulnerability Type: Insecure secret collection, handling, and storage
Risk Level: High

Vulnerable Code

text
| `setup_wallet` | Create a new wallet (saves PRIVATE_KEY to .env) |
markdown
## IMPORTANT: Private Key Handling

**For wallet operations, you MUST have PRIVATE_KEY set.**

If the user wants to create a wallet, transfer, or swap:
1. First ask: "Do you have an existing wallet private key, or should I create a new one?"
2. If new: Use `setup_wallet` to generate one
3. If existing: Ask user to provide PRIVATE_KEY and set it in environment

To call tools with PRIVATE_KEY:
```bash
PRIVATE_KEY=0x... mcporter call onlyswaps.check_setup chainId=8453
text

```bash
mcporter call onlyswaps.setup_wallet
# Returns: address and private key - SAVE THE PRIVATE KEY!
bash
PRIVATE_KEY=0x... mcporter call 'onlyswaps.check_setup(chainId: 8453)'
bash
PRIVATE_KEY=0x... mcporter call 'onlyswaps.transfer(tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", toAddress: "0xRecipientAddress", amount: "1000000", chainId: 8453)'
text
- Private keys are stored locally, never transmitted

Technical Analysis

The Skill instructs the agent to ask users for an existing raw private key and documents passing that key directly through an environment variable. It also states that newly generated keys are saved to a plaintext .env file and returned to the caller.

No controls are documented for encrypted storage, restrictive file permissions, transcript redaction, process-list exposure, shell history, backup exclusion, repository exclusion, or secure deletion. Asking for a private key through an agent conversation can also place the secret in conversation records, tool traces, telemetry, or logs.

The statement that private keys are “never transmitted” cannot be ver ...[truncated 1325 chars]

Remediation
View remediation

Remediation Suggestions

  • Never ask users to paste raw private keys into an agent conversation.
  • Integrate with a local wallet, hardware wallet, operating-system keychain, encrypted vault, or managed signer that does not export the private key.
  • Prefer scoped transaction-signing requests over granting a tool unrestricted access to raw signing material.
  • If local secret files are unavoidable, encrypt them at rest and enforce owner-only permissions.
  • Add secret files to .gitignore and backup-exclusion rules, and implement automated secret scanning.
  • Redact credentials from transcripts, command output, telemetry, exceptions, and tool logs.
  • Avoid passing secrets directly on shell command lines and minimize inheritance of secret-bearing environment variables.
  • Require users to use a dedicated wallet with limited funds and to verify every transaction on a trusted signing interface.
  • Document an immediate key-rotation and asset-migration procedure for suspected exposure.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:82
Finding

Contradictory Transfer Amount Formats Can Cause Oversized Transactions

Content
View full analysis

Vulnerability Details

File Locations: SKILL.md, lines 82-88 and 118-125
Vulnerability Type: Unsafe financial transaction parameter documentation
Risk Level: High

Vulnerable Code

markdown
| Tool | Format | Example |
|------|--------|---------|
| `get_quote` | wei (base units) | `"1000000000000000"` = 0.001 ETH |
| `swap` | wei (base units) | `"100000000000000000"` = 0.1 ETH |
| `transfer` | human readable | `"0.001"` = 0.001 tokens |
bash
### Transfer tokens (requires PRIVATE_KEY + funded wallet)
```bash
PRIVATE_KEY=0x... mcporter call 'onlyswaps.transfer(tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", toAddress: "0xRecipientAddress", amount: "1000000", chainId: 8453)'
text

### Technical Analysis

The amount-format table explicitly states that `transfer` accepts human-readable amounts, with `"0.001"` representing 0.001 tokens. The transfer example later supplies `"1000000"` for USDC, apparently treating the value as six-decimal base units.

If the documented human-readable interpretation is correct, the example requests a transfer of 1,000,000 USDC rather than one USDC. If the implementation instead expects base units, the format table is wrong. Either interpretation leaves users and agents without a reliable specification for constructing irreversible financial transactions.

No documented preflight validation, normalized amount display, balance-relative warning, fiat estimate, or final confirmation protects users from the discrepancy.

### Attack Path

1. A user or agent consults the transfer example to send one USDC.
2. The caller submits `amount: "1000000"` as shown.
3. The transfer implementation interprets the parameter according to the documented human-readable format.
4. The resulting transaction requests 1,000,000 USDC.
5. If the wallet has sufficient funds and the transaction is signed, the oversized transfer is broadcast.
6. Because blockchain tran
...[truncated 445 chars]
Remediation
View remediation

Remediation Suggestions

  • Establish one unambiguous amount format for transfer and correct either the table or the example.
  • Include an explicit parameter such as amountUnits: "human" or amountBaseUnits to prevent implicit interpretation.
  • Resolve and validate the selected token's decimal precision before transaction construction.
  • Display the normalized token amount, base-unit value, destination, chain, estimated fiat value, and fees before signing.
  • Require explicit user confirmation for every transfer, with additional confirmation for unusually large amounts.
  • Reject transfers exceeding configurable absolute or wallet-balance-relative thresholds.
  • Add automated tests covering native assets and tokens with differing decimal precision, including 6-, 8-, and 18-decimal assets.
  • Use a corrected USDC example such as "1" if the API expects human-readable units, or clearly document "1000000" as one USDC if it expects base units.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly instructs the agent to ask the user for a wallet private key and set it in the environment, normalizing direct collection and handling of one of the most sensitive credentials possible. In this context, compromise of that key gives full control of on-chain assets and cannot be mitigated once the secret is copied, logged, or reused elsewhere.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The example workflow states that setup_wallet returns an address and private key and tells the operator to save the private key, which encourages direct display and handling of the secret in a potentially logged interface. In an agent or MCP environment, responses may be persisted in chat logs, tool logs, terminal history, or observability systems, turning a single wallet creation event into permanent key exposure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document claims private keys are 'stored locally, never transmitted', but its own examples pass PRIVATE_KEY into an external MCP server process. Even if the process is local, the blanket claim is misleading and may cause operators to underestimate exposure through subprocesses, logs, shell history, environment inspection, telemetry, or any remote behavior inside the package.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The skill instructs users to execute an unpinned package via npx ...@latest, which causes code to be fetched and run at invocation time without version control or integrity pinning. Because this skill also supports sensitive wallet operations, a compromised or malicious package update could immediately gain access to private keys, transaction signing, or funds.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The examples describe wallet creation, transfer, and swap flows as routine operations without a prominent warning that these actions can irreversibly move real assets or permanently expose wallet control. In an AI-agent skill context, that omission is risky because users may treat tool calls as low-stakes automation rather than financially sensitive operations.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.