Back to skill

Security audit

Openclaw X402 Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is clearly meant for x402 service discovery and payments, but it asks users to give agents persistent wallet signing authority with incomplete payment controls.

Install only if you are comfortable giving the agent wallet signing authority. Use a dedicated low-balance wallet, testnet first, avoid putting valuable private keys in .env or desktop config files, verify each endpoint and price before payment, and do dependency installation in an isolated environment before adding wallet secrets.

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)

T09 · Insecure Skill Coding Practices

Error
Location
x402-MCP.md:136
Finding
Automatic Wallet Signing Lacks Payment and Network Restrictions<![CDATA[ ## Vulnerability Details **File Location**: `x402-MCP.md:136-163` **Vulnerability Type**: Unrestricted automatic cryptocurrency payment signing **Risk Level**: High ### Vulnerable Code ```typescript const evmPrivateKey = process.env.EVM_PRIVATE_KEY as `0x${string}`; const svmPrivateKey = process.env.SVM_PRIVATE_KEY as string; const baseURL = process.env.RESOURCE_SERVER_URL || "http://localhost:4021"; const endpointPath = process.env.ENDPOINT_PATH || "/weather"; if (!evmPrivateKey && !svmPrivateKey) { throw new Error("At least one of EVM_PRIVATE_KEY or SVM_PRIVATE_KEY must be provided"); } /** * Creates an axios client configured with x402 payment support for EVM and/or SVM. */ async function createClient() { const client = new x402Client(); // Register EVM scheme if private key is provided if (evmPrivateKey) { const evmSigner = privateKeyToAccount(evmPrivateKey); client.register("eip155:*", new ExactEvmScheme(evmSigner)); } // Register SVM scheme if private key is provided if (svmPrivateKey) { const svmSigner = await createKeyPairSignerFromBytes(base58.decode(svmPrivateKey)); client.register("solana:*", new ExactSvmScheme(svmSigner)); } return wrapAxiosWithPayment(axios.create({ baseURL }), client); } ``` The same unsafe wildcard registration pattern is repeated at `x402-MCP.md:252-265`. ### Technical Analysis The documented MCP implementation registers wallet signers for the wildcard network identifiers `eip155:*` and `solana:*`. It then wraps an HTTP client with automatic x402 payment handling for a configurable `RESOURCE_SERVER_URL`. The implementation does not locally validate or restrict: - The permitted blockchain network or chain ID - The payment token contract - The payment recipient - The maximum amount per request - The cumulative amount per session or day - The number of automatic payment attempts - Redirects to a different origin - Whether the user approved the exact payment terms Although `S ...[truncated 2135 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace wildcard scheme registration with an explicit allowlist of supported chain IDs, such as Base Mainnet or Base Sepolia only. 2. Allow only the expected USDC token contract for each approved network. 3. Validate the recipient against an explicit allowlist or require approval for a new recipient. 4. Enforce a hard maximum payment amount before creating any signature. 5. Add cumulative session, hourly, and daily spending limits. 6. Require interactive confirmation showing the endpoint, chain, token, recipient, and exact amount before payment. 7. Disable automatic cross-origin redirects or revalidate payment policy after every redirect. 8. Limit payment retries and prevent duplicate payment authorization for the same request. 9. Use a dedicated wallet funded only with the minimum amount needed for the task. 10. Record tamper-resistant payment audit logs without recording private keys or complete sensitive authorization payloads. 11. Add automated tests proving that excessive amounts, unsupported chains, unexpected tokens, and unknown recipients are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
x402-MCP.md:79
Finding
Raw Wallet Private Keys Are Stored in Persistent Plaintext Configuration<![CDATA[ ## Vulnerability Details **File Location**: `x402-MCP.md:79-90` **Vulnerability Type**: Plaintext storage of wallet credentials **Risk Level**: Medium ### Vulnerable Code ```json { "mcpServers": { "x402-bazaar": { "command": "pnpm", "args": [ "--silent", "-C", "<absolute path to x402 repo>/examples/typescript/clients/mcp", "dev" ], "env": { "EVM_PRIVATE_KEY": "<private key of wallet with USDC on Base Sepolia>", "SVM_PRIVATE_KEY": "<base58-encoded private key of Solana wallet with USDC>", "RESOURCE_SERVER_URL": "http://localhost:4021", "ENDPOINT_PATH": "/weather" } } } } ``` Related plaintext `.env` instructions also appear at `README.md:258-266`: ```bash # Create .env file cat > .env << EOF EVM_PRIVATE_KEY="0xYourPrivateKeyHere" MAX_SPEND_PER_CALL=0.10 BASE_RPC_URL="https://mainnet.base.org" EOF ``` ### Technical Analysis The documentation directs users to place complete EVM and Solana private keys in Claude Desktop configuration or project `.env` files. These are persistent plaintext files rather than dedicated secret stores. Excluding `.env` from version control reduces accidental Git disclosure but does not protect the credential from: - Other local processes running as the same user - Broad or inherited file permissions - Desktop configuration synchronization - Filesystem and cloud backups - Support bundles or accidental configuration sharing - Malware or compromised dependencies - Editors, shell history, or diagnostic tooling A wallet private key is a bearer credential. Anyone who obtains it can generally import the wallet and authorize transactions without requiring access to the original system. Raw private-key access is not the minimum privilege needed when an external signer, operating-system credential vault, or hardware-backed wallet can authorize narrowly scoped transactions. ### Attack Path 1. The user follows the setup gui ...[truncated 1104 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not place raw wallet private keys directly in Claude Desktop configuration. 2. Integrate with an operating-system keychain, hardware wallet, external signer, or narrowly scoped wallet service. 3. Use a dedicated agent wallet that contains only a small operational balance. 4. Where an `.env` fallback remains necessary, require restrictive file permissions such as owner read/write only. 5. Ensure configuration files are excluded from source control, backups, synchronization, support archives, and diagnostic output. 6. Avoid commands that insert real secrets through shell history. 7. Never log environment variables or signer initialization values. 8. Document immediate incident procedures: transfer remaining funds to a new wallet, revoke applicable token approvals, and permanently retire the exposed key. 9. Prefer transaction-specific authorization or session keys with strict amount, recipient, token, network, and expiration constraints. 10. Add startup checks that reject insecure file ownership or overly broad credential-file permissions. ]]>

T08 · Insecure Dependencies

Warning
Location
x402-MCP.md:55
Finding
Installation Instructions Execute Mutable and Unaudited Remote Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `x402-MCP.md:55-62` **Vulnerability Type**: Unpinned remote repository and dependency execution **Risk Level**: Medium ### Vulnerable Code ```bash # Clone the x402 repository git clone https://github.com/coinbase/x402.git cd x402/examples/typescript # Install dependencies and build packages pnpm install && pnpm build ``` Related installation instructions appear at `README.md:92-99`: ```bash # Clone the repository git clone https://github.com/coinvest518/openclaw-x402-skill.git cd openclaw-x402-skill # Install dependencies pip install -r requirements.txt ``` The Skill metadata also references an external manifest that is absent from the audited artifact at `SKILL.md:12-15`: ```yaml install: - id: pip kind: shell command: "pip install -r ~/clawd/skills/openclaw-x402-skill/requirements.txt" label: "Install Python dependencies" ``` ### Technical Analysis The installation process clones mutable repository default branches and immediately installs or builds their contents. No reviewed commit hash, signed release, dependency hash, or lockfile verification is specified. Package installation and build operations can execute lifecycle scripts and arbitrary build tooling with the installing user’s privileges. Consequently, the effective code executed by these instructions may change after the Skill documentation has been reviewed. The audited artifact contains only three Markdown files. It does not contain the referenced: - `agent.py` - `requirements.txt` - `requirements-dev.txt` - Package source - Lockfiles - `.env.example` - Tests Therefore, the advertised implementation and dependency graph cannot be audited from the supplied project. The installation paths are also inconsistent: `SKILL.md` references both `openclaw-x402-skill` and `x402-bazaar`. This is a supply-chain weakness rather than evidence that the currently named upstream repositories are malicious. ### Attack Path 1. An upstr ...[truncated 1430 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every cloned repository to a specific reviewed commit hash or signed release tag. 2. Verify release signatures or published checksums before installation. 3. Include dependency manifests and lockfiles in the Skill artifact so the complete dependency graph can be audited. 4. Pin Python dependencies to exact versions and cryptographic hashes. 5. Use frozen or immutable package-manager installation modes that reject lockfile changes. 6. Disable package lifecycle scripts unless they are explicitly required and reviewed. 7. Perform installation and builds in an isolated, unprivileged environment without wallet keys. 8. Separate dependency installation from runtime secret provisioning so build scripts cannot access private keys. 9. Scan dependencies for known vulnerabilities and suspicious install hooks. 10. Make all installation paths consistent and fail closed when the expected manifest is missing. 11. Include the actual executable implementation and tests in the reviewed package rather than relying on separately retrieved code. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (38)

Credential Access

High
Category
Privilege Escalation
Content
pip install -r requirements.txt

# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```

### Your First Query
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```

### Your First Query
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```

### Your First Query
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```

### Your First Query
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```

### Your First Query
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```

### Your First Query
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# (Optional) Set up environment for paid calls
cp .env.example .env
# Edit .env and add your EVM_PRIVATE_KEY
```

### Your First Query
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
3. **Configure environment:**
```bash
# Create .env file
cat > .env << EOF
EVM_PRIVATE_KEY="0xYourPrivateKeyHere"
MAX_SPEND_PER_CALL=0.10
Confidence
74% confidence
Finding
The README instructs users to place a raw blockchain private key in a plaintext .env file to enable autonomous paid calls. In an agent/skill ecosystem, this materially increases compromise risk because local secrets may be exposed through misconfiguration, logs, backups, directory syncing, or other tools with filesystem access; the skill context makes this more dangerous because the key directly authorizes spending.

Credential Access

High
Category
Privilege Escalation
Content
3. **Configure environment:**
```bash
# Create .env file
cat > .env << EOF
EVM_PRIVATE_KEY="0xYourPrivateKeyHere"
MAX_SPEND_PER_CALL=0.10
BASE_RPC_URL="https://mainnet.base.org"
Confidence
74% confidence
Finding
This example continues the plaintext .env setup containing EVM_PRIVATE_KEY and normalizes a high-risk secret-handling pattern for a tool that can autonomously spend funds. The danger is amplified by the financial capability of the key and by likely deployment in agent environments where multiple components may access local files.

Credential Access

High
Category
Privilege Escalation
Content
---
name: openclaw-x402-skill
description: "Discover, browse, filter, and pay for x402-compatible API endpoints and MCP tools from the x402 Bazaar — the autonomous discovery layer for agentic payments. Browse all available services, filter by price or type, inspect payment requirements, and call any discovered endpoint using USDC micropayments on Base with no API keys or account setup. Use when the agent needs to find a payable API service, check what x402 services exist for a given task (web scraping, AI inference, weather data, market data), pay for a single API call via x402, or list services under a given price threshold. Requires EVM_PRIVATE_KEY in .env (Base wallet with USDC) for paid calls. Discovery browsing requires no keys at all."
metadata:
  openclaw:
    emoji: "🛒"
Confidence
96% confidence
Finding
The skill metadata advertises that use of the paid features requires EVM_PRIVATE_KEY in .env, normalizing direct raw-key exposure as an operational prerequisite. For a payments skill, this materially raises the blast radius of any local compromise, accidental disclosure, prompt-induced file exposure, or logging issue because the secret controls spendable on-chain funds.

MCP Config Access

High
Category
Agent Snooping
Content
### Filter by type
```bash
python3 agent.py "list http services"
python3 agent.py "list mcp tools"
```

### Inspect a specific service
Confidence
80% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

MCP Config Access

High
Category
Agent Snooping
Content
### Filter by type
```bash
python3 agent.py "list http services"
python3 agent.py "list mcp tools"
```

### Inspect a specific service
Confidence
80% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

MCP Config Access

High
Category
Agent Snooping
Content
### Filter by type
```bash
python3 agent.py "list http services"
python3 agent.py "list mcp tools"
```

### Inspect a specific service
Confidence
80% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Credential Access

High
Category
Privilege Escalation
Content
| Error | Cause | Fix |
|---|---|---|
| `EVM_PRIVATE_KEY not set` | Missing .env key | Add key to .env (only needed for paid calls) |
| `Insufficient USDC balance` | Wallet underfunded | Bridge USDC to Base at bridge.base.org |
| `Spend limit exceeded` | Service costs more than MAX_SPEND_PER_CALL | Raise limit in .env or confirm manually |
| `402 verification failed` | Facilitator rejected payment | Retry or switch facilitator |
Confidence
92% confidence
Finding
The troubleshooting guidance tells users to add EVM_PRIVATE_KEY to .env, again encouraging placement of a highly sensitive secret into a commonly mishandled file. Repetition in operational guidance makes unsafe key-management practices more likely and broadens the chance of accidental disclosure during support, screenshots, copying commands, or repository use.

Credential Access

High
Category
Privilege Escalation
Content
|---|---|---|
| `EVM_PRIVATE_KEY not set` | Missing .env key | Add key to .env (only needed for paid calls) |
| `Insufficient USDC balance` | Wallet underfunded | Bridge USDC to Base at bridge.base.org |
| `Spend limit exceeded` | Service costs more than MAX_SPEND_PER_CALL | Raise limit in .env or confirm manually |
| `402 verification failed` | Facilitator rejected payment | Retry or switch facilitator |
| `No services found` | Empty Bazaar result | Broaden search or try again later |
| `Network mismatch` | Service on unsupported chain | Filter by network eip155:8453 |
Confidence
69% confidence
Finding
This finding is likely triggered because the table also references .env for MAX_SPEND_PER_CALL, which is a non-secret configuration value. Unlike the private key guidance, storing a spending-limit variable in .env is not credential access and does not itself expose sensitive authentication material.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README explicitly promotes autonomous paid calls and natural-language workflows that can send user prompts, URLs, and task data to third-party x402 services, but it does not clearly warn that sensitive user data may leave the local environment. In an agent setting, this omission is security-relevant because users may assume the skill only performs local discovery/payment orchestration while actually transmitting prompts and potentially confidential content to external providers.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Call a specific endpoint
python3 agent.py "call https://api.weather-x402.com/current?location=NYC"

# Pay and call with natural language
python3 agent.py "use x402 to get weather for London"
Confidence
86% confidence
Finding
This example instructs users to call a third-party endpoint directly and sits in the paid-execution section, where prompts and parameters are sent externally and payment is initiated. In the context of an agent skill, encouraging outbound calls without an explicit warning about data disclosure, untrusted remote services, and financial side effects is a real security concern.

External Transmission

Medium
Category
Data Exfiltration
Content
ENABLE_DEBUG=false              # Enable debug logging (default: false)

# Facilitator endpoints (advanced)
FACILITATOR_CDP="https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources"
FACILITATOR_PAYAI="https://facilitator.payai.network/discovery/resources"
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs users to export a wallet private key and place it in a local .env file without prominently warning that this credential grants direct control over funds. Encouraging routine handling of raw private keys materially increases the risk of theft through accidental exposure, logging, backup leakage, repository commits, or compromise of the host running the skill.

External Transmission

Medium
Category
Data Exfiltration
Content
### Inspect a specific service
```bash
python3 agent.py "inspect https://api.example.com/x402/weather"
```

### Call a discovered service (requires EVM_PRIVATE_KEY + USDC)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Inspect a specific service
```bash
python3 agent.py "inspect https://api.example.com/x402/weather"
```

### Call a discovered service (requires EVM_PRIVATE_KEY + USDC)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Inspect a specific service
```bash
python3 agent.py "inspect https://api.example.com/x402/weather"
```

### Call a discovered service (requires EVM_PRIVATE_KEY + USDC)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Inspect a specific service
```bash
python3 agent.py "inspect https://api.example.com/x402/weather"
```

### Call a discovered service (requires EVM_PRIVATE_KEY + USDC)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Call a discovered service (requires EVM_PRIVATE_KEY + USDC)
```bash
python3 agent.py "call https://api.example.com/x402/weather?location=NYC"
python3 agent.py "pay and call https://api.example.com/x402/sentiment"
```
Confidence
86% confidence
Finding
This example instructs the agent to call an arbitrary external x402 endpoint, which in the context of this skill can trigger an outbound paid request using the user's wallet. Because the skill is explicitly designed for autonomous payment to discovered or user-supplied endpoints, insufficient validation of destination trust or payment terms can lead to unintended spending, interaction with malicious APIs, or induced purchases.

Static analysis

No suspicious patterns detected.