Back to skill

Security audit

OKX a2a Payment

Security checks for vulnerabilities and agentic risk

Overview

The skill is openly a payment skill, but it directs agents to sign server-provided payment challenges without an in-skill preview or fresh confirmation, which deserves Review before installation.

Install only if you are comfortable with an agent invoking wallet-backed payment commands. Before using the buyer pay flow, independently verify the paymentId, amount, token, recipient, and network with the seller or upstream workflow, because this skill does not perform that check before signing.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:79
Finding

Blind Signing and Submission of Unverified Remote Payment Authorization

Content
View full analysis
**Trust model**: the buyer signs the seller's challenge as-is. Verifying that the challenge matches what the buyer agreed to pay is the **upstream caller's responsibility**: the user (or the upstream skill) MUST cross-check the seller's `paymentId` / `deliveries.url` against their out-of-band agreement (chat, task spec, prior negotiation) **before** calling this skill. Once the skill is invoked, it will sign the on-server challenge. #### Step 1 — Sign and Submit The skill does not run its own preview / yes-no gate; trust is delegated to the upstream caller (see the trust-model note above). Shell out directly: ```bash onchainos payment a2a-pay pay --payment-id ``` The CLI fetches the on-server challenge, TEE-signs the EIP-3009 authorization, and submits the credential. ``` ### Technical Analysis The Skill requires only a seller-issued `paymentId` to initiate payment. The material authorization fields—including the amount, currency, recipient, validity period, and potentially network or token-contract identity—are subsequently obtained from a remote server. The Skill explicitly directs the Agent to sign those remotely supplied terms without presenting them to the buyer or validating them against independently supplied expectations. Checking a `paymentId` or delivery URL out of band does not prove that the corresponding server-side challenge contains the agreed payment terms. The Skill has no local transaction preview, amount ceiling, recipient comparison, token-contract allowlist, chain verification, or fresh confirmation immediately before signing. ...[truncated 1978 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:60
Finding

Potential Shell Command Injection Through Unquoted User-Controlled Arguments

Content
View full analysis
--symbol --recipient \ [--description --realm --expires-in ] ``` ``` The same unsafe command-template pattern is used for the payment operation at lines 85–87: ```markdown The skill does not run its own preview / yes-no gate; trust is delegated to the upstream caller (see the trust-model note above). Shell out directly: ```bash onchainos payment a2a-pay pay --payment-id ``` ``` ### Technical Analysis The Skill instructs the Agent to “shell out” and presents user-controlled values as direct substitutions into command-line templates. It does not require structured process invocation, shell escaping, or strict lexical validation. The optional `description` field is free-form text and represents the clearest injection surface. Other parameters—including `paymentId`, `symbol`, `realm`, amount, recipient, and expiration—also lack explicit validation rules in the command-execution instructions. If an implementation follows the templates by building a command string and passing it to a shell, characters such as command separators, command substitutions, redirections, or quote delimiters can alter the command's meaning. For example, a malicious description containing shell syntax could cause an additional command to execute instead of being passed as one literal CLI argument. The documentation alone does not establish that the underlying `onchainos` executable is vulnerable. The risk occurs when the Agent or integration layer implements the documented “shell out” operation through a command-string shell interface. ### Attack Path 1. An attacker supplies a crafted `description`, `rea ...[truncated 1069 chars]
Remediation
View remediation
Vulnerability Patterns
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

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

md
| `expired`   | Expired before settlement | "⌛ Expired before settlement." |
   | `cancelled` | Seller cancelled | "🚫 Cancelled by seller." |

3. **Rendering the fee.** The CLI returns `fee_amount` as a top-level string in minimal units (and `fee_bps` as the basis-points used). To compute `<fee_decimal>`, look up the token decimals in the table under "Amount Display Rules". For `<fee_symbol>`, reuse the `--symbol` the seller passed to `create` for the same `paymentId` — the upstream caller (or the seller flow that issued the link) is the source of truth for the token symbol; the `status` response itself does not echo it back. If neither is available, display `fee_amount` minimal units as-is.

4. Suggest next:
   - `pending` / `settling` → "Check again in a few moments" or wait briefly and re-run `status`.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

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

md
| `expired`   | Expired before settlement | "⌛ Expired before settlement." |
   | `cancelled` | Seller cancelled | "🚫 Cancelled by seller." |

3. **Rendering the fee.** The CLI returns `fee_amount` as a top-level string in minimal units (and `fee_bps` as the basis-points used). To compute `<fee_decimal>`, look up the token decimals in the table under "Amount Display Rules". For `<fee_symbol>`, reuse the `--symbol` the seller passed to `create` for the same `paymentId` — the upstream caller (or the seller flow that issued the link) is the source of truth for the token symbol; the `status` response itself does not echo it back. If neither is available, display `fee_amount` minimal units as-is.

4. Suggest next:
   - `pending` / `settling` → "Check again in a few moments" or wait briefly and re-run `status`.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

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

md
| `expired`   | Expired before settlement | "⌛ Expired before settlement." |
   | `cancelled` | Seller cancelled | "🚫 Cancelled by seller." |

3. **Rendering the fee.** The CLI returns `fee_amount` as a top-level string in minimal units (and `fee_bps` as the basis-points used). To compute `<fee_decimal>`, look up the token decimals in the table under "Amount Display Rules". For `<fee_symbol>`, reuse the `--symbol` the seller passed to `create` for the same `paymentId` — the upstream caller (or the seller flow that issued the link) is the source of truth for the token symbol; the `status` response itself does not echo it back. If neither is available, display `fee_amount` minimal units as-is.

4. Suggest next:
   - `pending` / `settling` → "Check again in a few moments" or wait briefly and re-run `status`.

Static analysis

No suspicious patterns detected.