Back to skill

Security audit

x402 Quickstart

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed x402 API scaffold, but its payment-gating template and public-exposure guidance have material safety gaps users should review before using.

Install only if you are comfortable treating this as a prototype scaffold, not production-ready payment infrastructure. Validate project names, review generated files before running npm install or exposing a tunnel, add proper invoice or nonce-based payment binding with persistent atomic replay protection, and register endpoints publicly only after hardening authentication, rate limits, logging, and payment enforcement.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scaffold.sh:91
Finding

Payment Transactions Can Be Reused Across Restarts and Concurrent Requests

Content
View full analysis
{ if (valid) { usedTxHashes.add(txHash.toLowerCase()); next(); } else { res.status(402).json({ error: "Payment not verified", hint: "Ensure USDC was sent to the correct address on Base", }); } }); } ``` ### Technical Analysis The scaffold tracks redeemed transaction hashes in an in-memory JavaScript `Set`. This state is lost whenever the process restarts, is redeployed, or runs in another worker or server instance. The transaction check and insertion are also non-atomic. Multiple concurrent requests can all execute `usedTxHashes.has()` before any asynchronous `verifyPayment()` call finishes. Each request can consequently verify the same transaction successfully and reach the protected endpoint before the transaction is recorded as used. A multi-process or horizontally scaled deployment makes the issue worse because each process maintains a separate set. ### Attack Path 1. The attacker makes one valid USDC payment and obtains its transaction hash. ...[truncated 888 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scaffold.sh:57
Finding

Payment Transactions Are Not Bound to a Specific Request or Payer

Content
View full analysis
= priceWei ) { return true; } } } return false; } catch { return false; } } ``` ### Technical Analysis Verification only establishes that a successful receipt contains a transfer from the configured token contract to the configured wallet for at least the configured amount. It does not bind that transfer to: - A particular request or protected route - A server-issued nonce or invoice - An expiration time - The client presenting the transaction - A specific service when the wallet is shared - The exact requested amount rather than a general minimum Blockchain transaction hashes and transfer events are public. Therefore, possession of a qualifying transaction hash is treated as authorization even when the presenter did not make the payment or when the payment was intended for another request or service. The separate in-memory replay check reduces simple sequential reuse within one process, but it does not establish ownership or intended purpose ...[truncated 1083 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scaffold.sh:7
Finding

Unvalidated Project Name Permits Output Path Traversal

Content
View full analysis
}" DESC="${2:-My x402 API}" PRICE="${3:-0.01}" DIR="./$NAME" if [ -d "$DIR" ]; then echo "❌ Directory $DIR already exists" exit 1 fi echo "🚀 Scaffolding x402 endpoint: $NAME" mkdir -p "$DIR" # package.json cat > "$DIR/package.json" << EOF ``` ### Technical Analysis The script uses the caller-controlled `NAME` argument directly as a filesystem path. Quoting prevents shell word splitting and command substitution at this point, but it does not prevent path traversal. Values containing `../` or directory separators can resolve outside the intended current-directory destination. The existing-directory check only prevents operation when the complete destination already exists. It does not prevent the creation of a new directory outside the intended output root or subsequent creation of scaffold files there. ### Attack Path 1. An attacker or untrusted automation supplies a project name such as `../../target/new-service`. 2. `DIR` becomes `./../../target/new-service`. 3. If that final directory does not already exist, the directory check passes. 4. `mkdir -p` creates the directory outside the expected project location. 5. The script writes `package.json`, `.env`, `server.js`, and `.gitignore` into that external directory. 6. The files are created with the privileges of the user running the scaffold. Successful exploitation requires the victim process to have write permission to the selected destination. ### Impact Assessment A caller who can influence script arguments can create directories and write known or partially attacker-influenced files outside the intended scaffold directory. The scope is limited to filesystem locations writable by the invoking user. The issue does not i ...[truncated 165 chars]
Remediation
View remediation
&2 exit 1 } ``` - Reject absolute paths, `..`, slashes, backslashes, control characters, and empty names. - Select an explicit output root and resolve both the root and destination to canonical paths. - Verify that the canonical destination remains a child of the canonical output root before creating files. - Create the final directory atomically and fail if it already exists. - Avoid running the scaffold with elevated privileges. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/scaffold.sh:20
Finding

Unescaped Arguments Can Corrupt or Inject Generated Configuration

Content
View full analysis
"$DIR/package.json" << EOF { "name": "$NAME", "version": "1.0.0", "description": "$DESC", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "^4.21.0", "ethers": "^6.13.0" } } EOF # .env cat > "$DIR/.env" << EOF # x402 Configuration WALLET_ADDRESS=0xYOUR_BASE_WALLET_ADDRESS USDC_CONTRACT=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 CHAIN_ID=8453 PORT=3402 PRICE_USDC=$PRICE BASE_RPC=https://mainnet.base.org EOF ``` ### Technical Analysis `NAME` and `DESC` are inserted directly into JSON string literals without JSON encoding. Quotes, backslashes, newlines, and other control characters can make `package.json` invalid or alter its structure. `PRICE` is inserted directly into `.env` without validation or dotenv-safe encoding. A value containing a newline can append or override environment entries. Although shell metacharacters in these variables are not recursively evaluated by the shell during expansion, the generated configuration can still be malformed or attacker-influenced and will be consumed by later tools. A crafted package description or name can also cause the subsequent Python JSON parsing step to fail. A crafted price can alter generated environment settings, although the fixed configuration lines following `PRICE_USDC` constrain which earlier values can be persistently overridden under common dotenv parsing behavior. ### Attack Path 1. An attacker or untrusted automation controls one or more scaffold arguments. 2. The attacker supplies JSON metacharacters in the name or description, or newline-delimited dotenv content in the price. 3. The here-documents write the values without format-specific escaping. 4. The generated JSON becomes malf ...[truncated 850 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The code largely aligns with the monetized x402 endpoint theme: it creates a project containing payment verification logic, pricing metadata, and a sample pay-per-call API using USDC on Base. However, the declared description overstates the behavior in important ways. This chunk does not deploy endpoints; it scaffolds a local project directory and leaves installation, configuration, running, and tunnel setup to the user. It also does not implement actual Cloudflare Tunnel integration beyond printing a suggested command. Therefore, the description is directionally related but not fully accurate about the code’s actual primary behavior and capabilities.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

Set your Base wallet address to receive payments:

bash
# In the generated .env file
WALLET_ADDRESS=0xYourBaseWalletAddress
USDC_CONTRACT=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
CHAIN_ID=8453

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/scaffold.sh (reported line 37)May include surrounding context.

sh
Set your Base wallet address to receive payments:

```bash
# In the generated .env file
WALLET_ADDRESS=0xYourBaseWalletAddress
USDC_CONTRACT=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
CHAIN_ID=8453

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/scaffold.sh (reported line 178)May include surrounding context.

sh
Set your Base wallet address to receive payments:

```bash
# In the generated .env file
WALLET_ADDRESS=0xYourBaseWalletAddress
USDC_CONTRACT=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
CHAIN_ID=8453

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/scaffold.sh (reported line 194)May include surrounding context.

sh
Set your Base wallet address to receive payments:

```bash
# In the generated .env file
WALLET_ADDRESS=0xYourBaseWalletAddress
USDC_CONTRACT=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
CHAIN_ID=8453

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/scaffold.sh (reported line 38)May include surrounding context.

sh
EOF

# .env
cat > "$DIR/.env" << EOF
# x402 Configuration
WALLET_ADDRESS=0xYOUR_BASE_WALLET_ADDRESS
USDC_CONTRACT=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents shell commands and environment-file handling but does not declare any tool scope or allowed-tools restrictions. In agent ecosystems, this increases the chance that an agent may execute shell-capable steps without explicit least-privilege boundaries, which can lead to unintended command execution or environment access when the skill is invoked.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs users to expose a localhost service through Cloudflare Tunnel without warning that this makes the service publicly reachable. In context, this is more dangerous because the skill is specifically about monetized API deployment, so users may expose unfinished local services, admin routes, debugging endpoints, or weak payment verification logic to the internet.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The curl example explicitly transmits endpoint metadata to an external service. This is not inherently malicious, but it is an external data transfer that can expose infrastructure details and increase attack surface by advertising a reachable API endpoint to a third party and, indirectly, to downstream consumers.

Content

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

Register your endpoint on Spraay to get discovered by agents automatically:

bash
curl -X POST https://gateway.spraay.app/register \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.mydomain.com", "category": "data", "price": "0.01"}'

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill recommends registering the endpoint with a third-party gateway but does not disclose that service metadata will be transmitted externally. While the shared data shown is limited, publishing endpoint URLs, category, and pricing can create privacy, discovery, and targeting risks, especially for newly exposed services.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.