Back to skill

Security audit

Agent APIs x402 Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is coherent for paid x402 API calls, but it gives an agent automatic payment-signing authority and public image-upload behavior without enough user control or payment validation.

Review before installing. Use only a dedicated low-balance wallet, pin the API URL to the intended service, require manual confirmation for each paid request, and avoid uploading private or regulated images unless you intend them to become externally hosted.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:121
Finding

Unvalidated Server-Directed Cryptocurrency Payment

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 121-124 and 140-161
Vulnerability Type: Unvalidated payment authorization to an environment-controlled endpoint
Risk Level: High

Vulnerable Code

ts
const baseUrl =
  process.env.X402_API_BASE_URL ??
  process.env.API_BASE_URL ??
  "https://www.x402api.app/";
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/qrcode/generate`;
ts
const unpaid = await fetch(endpoint, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify(payload),
});

if (unpaid.status !== 402) {
  const unpaidBody = await unpaid.text();
  throw new Error(`Expected unpaid status 402, got ${unpaid.status}. body=${unpaidBody}`);
}

const paymentRequired = httpClient.getPaymentRequiredResponse(
  (name) => unpaid.headers.get(name),
  {},
);

const paymentPayload = await httpClient.createPaymentPayload(paymentRequired);
const response = await fetch(endpoint, {
  method: "POST",
  headers: {
    "content-type": "application/json",
    ...httpClient.encodePaymentSignatureHeader(paymentPayload),
  },
  body: JSON.stringify(payload),
});

Technical Analysis

The client permits X402_API_BASE_URL or API_BASE_URL to determine the service origin. It then accepts payment requirements from that origin and passes them directly to createPaymentPayload. The example performs no explicit validation of the expected network, payment scheme, asset, recipient, amount, expiration, or API origin before authorizing the payment.

An HTTP 402 Payment Required status establishes only that the remote server returned the expected status code; it does not establish that the requested payment is legitimate or within the user's intended spending limits. If the environment configuration is modified or the configured service is compromised, the responding server can supply attacker-selected payment requirements.

...[truncated 1419 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin the API to an exact HTTPS origin or enforce a strict hostname and port allowlist. Do not accept arbitrary environment-provided origins without validation.
  2. Reject URL credentials, non-HTTPS protocols, unexpected ports, and origins whose normalized hostname does not exactly match the approved service.
  3. Disable redirects or verify that every redirect target and the final response origin remain allowlisted.
  4. Before signing, validate the payment network and chain ID, scheme, asset or token contract, recipient address, amount, expiration, and request association against locally configured expectations.
  5. Enforce strict per-request, per-session, and cumulative spending caps.
  6. Require explicit user confirmation when the recipient changes, the asset changes, or the requested amount exceeds a low predefined threshold.
  7. Bind the payment authorization to the intended method, endpoint, payload, and trusted origin where supported by the protocol.
  8. Use a dedicated, low-balance wallet with narrowly scoped allowances rather than a primary wallet.
  9. Record payment destination, asset, amount, network, and request identifier in security logs without logging the private key or reusable sensitive authorization material.
  10. Add negative tests covering malicious 402 responses, excessive amounts, unexpected recipients, unsupported networks, redirects, malformed requirements, and attacker-controlled base URLs.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill advertises image upload capability but does not clearly warn that images are sent to a third-party remote service and that the response is a public URL. Users or agents may therefore upload sensitive, private, or regulated images under the mistaken assumption that processing is local or private, leading to confidentiality and privacy exposure. The context makes this more dangerous because the feature is specifically an image-hosting service, which implies publication rather than transient processing.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The quick-start tells users to prompt the agent with very broad natural-language phrases like converting text to a QR code or uploading an image. In agent environments, such generic triggers can match ordinary conversation and cause the skill to activate unexpectedly, potentially initiating paid API calls or data uploads without sufficiently explicit user intent. The risk is heightened here because the skill performs remote network actions and participates in a payment flow.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.