T09 · Insecure Skill Coding Practices
- Location
SKILL.md:51- Finding
Remote Payment Requirements Are Trusted Without Local Authorization Controls
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 51-65
Vulnerability Type: Unvalidated remote payment authorization
Risk Level: HighVulnerable Instructions:
markdown 3. Select a `paymentRequirement` from `accepts[]` matching your preferred network + asset. 4. Networks: `cardano:mainnet` (ADA, DJED, iUSD, USDCx, USDM), `stellar:pubnet` (USDC, XLM), `sandbox` (free). 5. Send payment to the `payTo` address for `maxAmountRequired` in the specified asset. 6. **Stellar fee sponsorship:** POST your signed XDR to `https://ai-service-hub-15.emergent.host/api/mpp/stellar/sponsor` — NEXUS pays gas, you need 0 XLM. 7. Retry with `X-PAYMENT: <base64url JSON {x402Version:1, scheme:"exact", network, payload:{tx_hash, currency}}>` header. 8. Parse the JSON response and `X-PAYMENT-RESPONSE` header. ### Option B: MPP Standard 1. Call the service endpoint without payment headers. 2. Receive HTTP 402 with `WWW-Authenticate: Payment` header listing all accepted currencies and amounts. 3. Pick your preferred chain + currency: Cardano (ADA, stablecoins) or Stellar (USDC, XLM). 4. Create payment: Masumi escrow (Cardano) or direct Stellar transfer. 5. **Stellar fee sponsorship:** POST your signed XDR to `https://ai-service-hub-15.emergent.host/api/mpp/stellar/sponsor` — NEXUS pays gas, you need 0 XLM.Technical Analysis
The skill instructs an agent to derive the payment recipient and amount from a remotely supplied HTTP 402 challenge and then issue a cryptocurrency payment. The remote
payToandmaxAmountRequiredvalues are not subject to documented local validation.Although the skill advertises a price of
$0.75/request, it does not require the agent to verify that the challenge corresponds to that price. It also does not establish:- A locally enforced maximum payment amount.
- An allowlist or pinned recipient address.
- Explicit user approval immediately before signing or broadcast ...[truncated 2309 chars]
- Remediation
View remediation
Remediation Suggestions
- Require explicit, transaction-specific user confirmation immediately before signing or broadcasting any non-sandbox payment. Display the recipient, network, asset, exact fiat-equivalent value, fees, and total amount.
- Enforce a local hard ceiling matching the advertised
$0.75price, with an explicitly documented tolerance for conversion and network fees. Reject challenges exceeding that ceiling rather than relying on the server-providedmaxAmountRequired. - Pin or locally allowlist expected recipient addresses for every supported network and asset. Treat any remote recipient change as an error requiring out-of-band verification.
- Validate the complete payment challenge, including network, asset identifier, amount, recipient address format, expiration time, service identity, and cryptographic signature.
- Bind each payment challenge to the originating request using a nonce, request digest, service identifier, and short expiration period. Persist transaction identifiers sufficiently to reject replay attempts.
- Apply wallet-level policies such as per-transaction limits, daily limits, recipient allowlists, and denial of unattended transfers.
- For Stellar sponsorship, decode and present the complete XDR contents before signing or submission. Confirm that the transaction contains only the intended payment and does not include unexpected operations or authorization changes.
- Separate challenge discovery from payment authorization so that data returned by the service cannot itself authorize spending.
- Document failure behavior explicitly: reject malformed, unsigned, expired, mismatched, unexpectedly priced, or unsupported payment requirements.
