Back to skill

Security audit

ROZO Intents Pay & Bridge

Security checks for vulnerabilities and agentic risk

Overview

This Rozo payment skill is coherent, but it needs Review because it handles irreversible crypto transfers with unsafe command templates, optional no-confirmation execution, and an unaudited external wallet-funding command.

Review carefully before installing. This skill sends wallet addresses, payment details, and status identifiers to Rozo, and Stellar trustline checks also contact Horizon. Keep version.json confirmation thresholds at 0 unless you intentionally accept no-confirmation payments, and do not run the documented shell commands with untrusted QR or memo text unless arguments are passed safely without shell interpolation.

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
skills/parse-qr/SKILL.md:36
Finding

<![CDATA[Shell Command Injection Through Attacker-Controlled Payment Parameters]]>

Content
View full analysis
" ``` The payment creation instructions similarly interpolate addresses, amounts, and memos: ```bash node scripts/dist/create-payment.js \ --source-chain \ --source-token \ --dest-chain \ --dest-address \ --dest-token \ --dest-amount \ --dest-memo ``` Payment-status lookups also embed user-provided identifiers: ```bash node scripts/dist/get-payment.js --payment-id node scripts/dist/get-payment.js --tx-hash node scripts/dist/get-payment.js --receiver-address --receiver-memo ``` The balance workflow uses the same construction: ```bash node scripts/dist/check-balance.js --address ``` ### Technical Analysis QR payloads, wallet addresses, memos, payment IDs, transaction hashes, and amounts originate from users or external payment requests. The Skill directs the Agent to substitute these values into shell command templates rather than pass them through a non-shell argument-array interface. The JavaScript programs read values from `process.argv`, which is safe only after the process has started. If an Agent constructs and executes the documented command through a shell, shell syntax is interpreted before Node receives the arguments. Quoting QR content with double quotes is insufficient because command substitutions such as `$(...)` and bac ...[truncated 1839 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
skills/send-payment/SKILL.md:259
Finding

<![CDATA[Unpinned npx Dependency Executes an Unverified External Wallet Script]]>

Content
View full analysis
\ --chain stellar \ --amount \ --yes ``` The audited project does not contain `skills/send-payment/run.ts`. ### Technical Analysis The funding workflow invokes `npx tsx` without an exact version, lockfile reference, or integrity constraint. If `tsx` is not already installed in the execution environment, `npx` may retrieve and execute a package from the npm registry at runtime. Consequently, the code that executes can differ from the code reviewed during the audit. The command then runs a relative `skills/send-payment/run.ts` file that is not included in this package. Its origin, integrity, and behavior therefore cannot be verified from the audited artifact. Resolution depends on an external plugin or the current working directory, increasing the possibility of path substitution or execution of an unexpected file. The `--yes` argument suppresses confirmation in the delegated payment process. This amplifies the consequences of dependency compromise or script substitution because the external component is invoked in a wallet-funding context with non-interactive approval. ### Attack Path 1. A payment reaches the Stellar funding stage. 2. The Agent executes the documented `npx tsx` command. 3. If `tsx` is unavailable locally, `npx` resolves and downloads an unpinned package version. 4. The package executes code that was not included in the audited Skill. 5. The relative `run.ts` path resolves to an externally installed or locally substituted script. 6. The script receives a deposit address, payment amount, chain selection, and the `--yes` confirmation-bypass option. 7. A compromised dependency or substituted script can execute arbitrary local code or manipulate the wallet operation. ...[truncated 761 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
SKILL.md:25
Finding

<![CDATA[Stellar Horizon Network Access Is Missing From the Declared Permissions]]>

Content
View full analysis
` from `horizon.stellar.org`. 4. The recipient’s Stellar address and the requester’s network metadata are disclosed to an endpoint not listed in the Skill permission declaration. ### Impact Assessment The issue does not expose private keys or seed phrases and does not independently enable code execu ...[truncated 402 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
85% confidence
Finding

Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Content

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

md
| Solana | Yes | Yes |
| Stellar | Yes | No |

**Trust the live API over these tables.** Do NOT refuse a user's request
based purely on the tables above. Tables can be stale or misread — always
call `create-payment.js --dryrun` first and let the API be the source of
truth. If dryrun returns `success: true`, the route is supported; if it

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `check-balance.js` | Fetch wallet balances via Rozo balance API |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `check-stellar-trustline.js` | Verify asset trustline (USDC/EURC) on Stellar G-wallets |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `create-payment.js` | Create a payment (or dryrun for fee estimate) via Rozo API |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `get-payment.js` | Get payment status by ID, tx hash, or address+memo |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `parse-qr.js` | Parse payment QR code URIs (EIP-681, Solana Pay, Stellar URI) |

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

The instruction to suppress routing memo disclosure is dangerous because this same skill later acknowledges that some payment paths require the memo for correct routing and that omission can lose funds. In an irreversible cross-chain payment context, hiding routing-critical information from the user can directly cause failed or misapplied deposits.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
92% confidence
Finding

This skill introduces an auto-execute path for financial transactions, even if disabled by default. In a payments context, allowing standing consent via threshold configuration increases the chance of unintended, spoofed, or prompt-induced transfers occurring without per-transaction confirmation, especially when the skill also auto-detects wallet type and token.

Content

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

md
G/C stellar), or a transaction hash. Auto-detects wallet type and
  auto-selects token (USDC preferred).
  Every payment shows full details and waits for an explicit yes/no by
  default. Small-amount auto-execute is opt-in: it runs only if the user
  raises the confirmation thresholds in version.json (shipped 0 = off).
  Do NOT use for general blockchain questions, non-payment tasks, or
  ordinary fiat payments, bank transfers, or bank-account balance questions.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
94% confidence
Finding

The permissions section confirms that the skill can create payment intents and may auto-execute below configured thresholds. In a crypto-transfer skill, that is materially risky because blockchain payments are irreversible and an attacker may exploit user confusion, address substitution, or conversational manipulation to trigger low-value transfers repeatedly without fresh approval.

Content

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

md
filesystem: none — scripts read/write no files; the agent reads
      version.json for confirmation thresholds
    spending: creates Rozo payment intents; every payment prompts for an
      explicit yes/no by default. Auto-execute below user-raised thresholds
      is opt-in via version.json and ships disabled (0/0).
    subprocess: none — scripts run via node with no child processes
---

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
93% confidence
Finding

Even though auto-execute ships off, the documented capability is dangerous in this context because it normalizes autonomous execution of irreversible crypto payments once enabled. For a payment/bridging skill, context makes this significantly more severe than in low-risk domains, since errors or abuse directly cause asset loss.

Content

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

md
(Base and Stellar are USDC-only; Solana receives USDC only but can pay in USDT).

**Confirmation:** every payment, any amount, shows full details and waits
for an explicit yes/no. Small-amount auto-execute exists but ships OFF
(thresholds `0` in `version.json`); it runs only if the user raises them.

## Before any payment

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

This section explicitly says the per-payment restatement is not required when standing auto-execute thresholds apply. Waiving transaction-by-transaction restatement in an irreversible crypto payment flow materially increases the likelihood of misdirected funds, memo omissions, address poisoning success, and prompt-injection-driven execution without the user noticing critical details.

Content

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

md
have the user verify the destination address, chain, token, memo (Stellar)
and amount against a source they trust. A payment to a wrong address, wrong
chain, or without a required memo is not recoverable by Rozo or anyone else. (If the
user has deliberately raised the auto-execute thresholds, their standing
opt-in covers amounts below them — correctness checks still run, but the
per-payment restatement is not required there.)

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| Intent | Sub-skill | Triggers |
|--------|-----------|----------|
| Send a payment | `skills/send-payment/SKILL.md` | "pay", "send", "transfer", "payout", shares a QR code, provides an amount + address |
| Check wallet balance | `skills/check-balance/SKILL.md` | "check balance", "how much do I have", "show my balance", "wallet balance" |
| Parse a QR code | `skills/parse-qr/SKILL.md` | "scan QR", "parse QR", "read this QR", shares a QR image without mentioning payment |
| Check payment status | `skills/payment-status/SKILL.md` | "check payment", "payment status", "where is my payment", "track payment", provides a payment UUID or tx hash |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| Intent | Sub-skill | Triggers |
|--------|-----------|----------|
| Send a payment | `skills/send-payment/SKILL.md` | "pay", "send", "transfer", "payout", shares a QR code, provides an amount + address |
| Check wallet balance | `skills/check-balance/SKILL.md` | "check balance", "how much do I have", "show my balance", "wallet balance" |
| Parse a QR code | `skills/parse-qr/SKILL.md` | "scan QR", "parse QR", "read this QR", shares a QR image without mentioning payment |
| Check payment status | `skills/payment-status/SKILL.md` | "check payment", "payment status", "where is my payment", "track payment", provides a payment UUID or tx hash |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
|--------|-----------|----------|
| Send a payment | `skills/send-payment/SKILL.md` | "pay", "send", "transfer", "payout", shares a QR code, provides an amount + address |
| Check wallet balance | `skills/check-balance/SKILL.md` | "check balance", "how much do I have", "show my balance", "wallet balance" |
| Parse a QR code | `skills/parse-qr/SKILL.md` | "scan QR", "parse QR", "read this QR", shares a QR image without mentioning payment |
| Check payment status | `skills/payment-status/SKILL.md` | "check payment", "payment status", "where is my payment", "track payment", provides a payment UUID or tx hash |

**Rules:**

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
| Send a payment | `skills/send-payment/SKILL.md` | "pay", "send", "transfer", "payout", shares a QR code, provides an amount + address |
| Check wallet balance | `skills/check-balance/SKILL.md` | "check balance", "how much do I have", "show my balance", "wallet balance" |
| Parse a QR code | `skills/parse-qr/SKILL.md` | "scan QR", "parse QR", "read this QR", shares a QR image without mentioning payment |
| Check payment status | `skills/payment-status/SKILL.md` | "check payment", "payment status", "where is my payment", "track payment", provides a payment UUID or tx hash |

**Rules:**
1. If the user mentions sending/paying → route to `send-payment` (it handles QR parsing internally)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code performs an HTTP POST to a third-party payment API and includes user-supplied payment data such as receiverAddress, token information, amount, and optional memo in the request body. While the network call is core to the function's purpose, the file provides no confirmation prompt or explicit user-facing warning in the CLI path before transmitting that data externally.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The parser explicitly accepts generic EIP-681 native-token payment URIs and returns them as valid parse results even when no recognized stablecoin contract is present. In this skill, that broadens the supported payment scope beyond the manifest’s stated USDC/USDT-focused behavior and can cause downstream payment logic or users to act on ETH/BNB/MATIC-style transfers that the skill should not be handling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The Stellar URI parser accepts any asset_code value and returns it as the token without restricting it to the skill’s declared Stellar scope. Because the skill metadata says Stellar payments are limited to USDC and EURC is trustline-check-only, accepting arbitrary asset codes could misclassify unsupported assets as payable and expose users to incorrect or unsafe payment flows.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description includes broad trigger phrases like "check my crypto payment," "payment status," and "where is my payment," which can cause the skill to activate on loosely related user requests. In a payment-oriented skill, overbroad invocation increases the chance the agent routes sensitive financial queries here unnecessarily, potentially causing confusion, unintended data handling, or use of payment-tracking logic when another tool or clarification would be safer.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest description says to use the skill when the user says "pay", "send", "transfer", or "payout", which are common everyday phrases. Although the text adds crypto-related qualifiers and excludes ordinary fiat payments, it does not provide a constrained trigger list or negative examples robust enough to prevent unintended invocation in ambiguous conversations.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

The skill advertises small-amount auto-execute capability, which normalizes unattended transfer execution in a system handling irreversible payments. Even if disabled by default, the presence of the feature materially expands risk once enabled because a misparsed request or injected instruction can directly move funds without an immediate yes/no checkpoint.

Content

Scanner excerpt · skills/send-payment/SKILL.md (reported line 12)May include surrounding context.

md
payments or bank transfers. Also handles QR code screenshots containing
  payment URIs (EIP-681, Solana Pay, Stellar URI). Auto-detects wallet
  type, auto-selects token (USDC preferred). Every payment shows full
  details and waits for an explicit yes/no; small-amount auto-execute is
  opt-in and ships disabled (thresholds 0 in version.json).
metadata:
  author: rozo

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
89% confidence
Finding

This section expressly allows irreversible transfers to proceed without per-payment restatement when user-configured thresholds are set. For financial actions, reducing real-time verification on the basis of prior standing consent increases the impact of any parsing error, stale context, or malicious prompt content.

Content

Scanner excerpt · skills/send-payment/SKILL.md (reported line 34)May include surrounding context.

md
**Every transfer this skill creates is irreversible once funded.** Verify
destination address, chain, token, memo and amount with the user before
funding; a mistake is not recoverable by Rozo. (If the
user has deliberately raised the auto-execute thresholds, their standing
opt-in covers amounts below them — correctness checks still run, but the
per-payment restatement is not required there.)

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
86% confidence
Finding

Defining an auto-execute mechanism for payments is itself a security-relevant weakness because it permits execution without contemporaneous user confirmation. In a cross-chain crypto context where mistakes are not reversible, even opt-in autonomy meaningfully raises loss exposure.

Content

Scanner excerpt · skills/send-payment/SKILL.md (reported line 40)May include surrounding context.

md
## Confirmation Thresholds

**Auto-execute is OFF by default.** Both thresholds ship as `0`: every
payment, any amount, gets a full summary and an explicit yes/no. A user who
wants small amounts to run unprompted must raise the thresholds in
`version.json` themselves — that is the opt-in.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
87% confidence
Finding

The documented thresholds explicitly authorize silent and narrated auto-execution below configured limits. That creates a direct path for low-value but unauthorized or repeated transfers, which can be abused cumulatively and are difficult to reverse in blockchain systems.

Content

Scanner excerpt · skills/send-payment/SKILL.md (reported line 47)May include surrounding context.

md
Read `version.json` at the plugin root for the current thresholds:

- `freeConfirmThresholdUsd` (default `0` = disabled) — at or below: silent auto-execute
- `singleConfirmThresholdUsd` (default `0` = disabled) — at or below: narrated auto-execute

**Auto-execute is OFF by default.** With the shipped `0`/`0` every payment,

Static analysis

No suspicious patterns detected.