Back to skill

Security audit

Solana Payments

Security checks for vulnerabilities and agentic risk

Overview

This payment-skill guide is coherent overall, but it under-discloses important recurring-payment authority, URL privacy, and checkout-domain risks.

Review this carefully before installing or following it. Use it only after independently verifying the Tributary/Lando domains, SDK package names, and fixed gateway public key; require explicit customer opt-in before autoRenew; avoid putting personal data or secrets in tracking IDs, memos, line items, or URLs; and document cancellation and revocation paths for recurring payments.

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

T08 · Insecure Dependencies

Warning
Location
skill.md:22
Finding
Unpinned and Inconsistent Payment SDK Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:22-26` **Vulnerability Type**: Unpinned third-party dependency and package mismatch **Risk Level**: Medium ### Vulnerable Code ```bash npm install @tributary-so/sdk ``` ```typescript import { CheckoutSessionManager } from "@tributary-so/payments"; ``` ### Technical Analysis The installation command names `@tributary-so/sdk`, while the example imports `CheckoutSessionManager` from the separate `@tributary-so/payments` package. The document does not explain this discrepancy or provide an installation command for the imported package. Neither dependency is pinned to a reviewed version. Consequently, executing the installation command resolves the package version from the registry at installation time. The effective dependency code can therefore change without any corresponding change to the audited Skill. Because these packages participate in constructing payment sessions and transaction destinations, a compromised or malicious release could alter checkout parameters, redirect users, capture payment metadata, or execute arbitrary package lifecycle code in the developer environment. ### Attack Path 1. An attacker compromises the publisher account, package registry entry, or a transitive dependency associated with the unpinned package. 2. The attacker publishes a malicious version while retaining the expected package name and API. 3. A developer follows the Skill and installs the package without a version or integrity constraint. 4. The package manager resolves the malicious release. 5. Malicious lifecycle or runtime code executes with the permissions of the developer process. 6. The package may steal environment credentials, alter generated payment destinations, or redirect checkout sessions. ### Impact Assessment Successful exploitation could execute code under the developer or build process account. The resulting scope depends on that account's permissions and may include access to source c ...[truncated 196 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Correct the package mismatch and explicitly document every required package. - Pin each dependency to a specific reviewed version, for example with an exact version rather than a range. - Commit and enforce a package-manager lockfile with integrity hashes. - Use reproducible installation commands such as `npm ci` in automated builds. - Disable package lifecycle scripts where they are unnecessary. - Review package provenance, publisher identity, release signatures, and transitive dependencies. - Add automated dependency vulnerability and integrity monitoring. - Re-review the dependency before upgrading versions, particularly because it handles payment configuration. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
skill.md:364
Finding
Mandatory Third-Party Gateway Can Trigger Recurring Payments<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:46` and `skill.md:364-366` **Vulnerability Type**: Unverified fixed payment authority with recurring-payment privileges **Risk Level**: High ### Vulnerable Code ```typescript gateway: "CwNybLVQ3sVmcZ3Q1veS6x99gUZcAF2duNDe3qbcEMGr", // fixed, do not change ``` ```text Further, the gateway pubkey must be `CwNybLVQ3sVmcZ3Q1veS6x99gUZcAF2duNDe3qbcEMGr` and must not be changed as this enables and operator to trigger payments when they become due! ``` ### Technical Analysis The Skill mandates a fixed Solana gateway public key and instructs agents not to change it. It explicitly states that the associated operator can trigger payments when they become due. This delegates recurring-payment authority to an externally controlled identity. The Skill does not provide authoritative deployment records, ownership verification, environment-specific gateway addresses, spending limits, revocation procedures, or controls that bind the gateway's authority to a narrowly defined merchant and subscription. The issue is especially significant when `autoRenew` is enabled. A user may believe they are merely opening a hosted checkout page while the resulting authorization grants an external operator continuing ability to initiate due payments. ### Attack Path 1. An agent follows the Skill and embeds the mandatory gateway public key in a checkout session. 2. The checkout is configured as a subscription, potentially with `autoRenew: true`. 3. A customer approves the subscription and the associated on-chain authorization. 4. The holder of the gateway authority triggers payments when they become due. 5. If the operator is malicious, compromised, or operating beyond the customer's expectations, it can exercise the delegated authority until the authorization is revoked or otherwise expires. 6. In the absence of documented limits and revocation controls, multiple subscriptions or renewals may remain exposed. ### Impact Ass ...[truncated 470 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Verify the gateway address against authoritative and independently authenticated deployment records. - Document the legal and technical identity of the gateway operator. - Support merchant-controlled or explicitly configurable gateway authorities instead of silently mandating one global address. - Separate production, testnet, development, and merchant-specific gateway configurations. - Clearly disclose the delegated recurring-payment authority before customer approval. - Require explicit customer consent for automatic renewal. - Enforce on-chain spending ceilings, renewal-count limits, frequency restrictions, and expiration times. - Provide a documented, easily accessible revocation mechanism. - Display the gateway, token mint, recipient, amount, frequency, and maximum authorization to the customer before signing. - Monitor gateway activity and alert customers and merchants about renewals and anomalous payment attempts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
skill.md:116
Finding
Subscription and Customer-Linked Metadata Exposed in Encoded Checkout URLs<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:116-138` **Vulnerability Type**: Sensitive transaction metadata placed in reversible URL encoding **Risk Level**: Medium ### Vulnerable Code ```text ### 3. URL Format The checkout URL contains Base64URL-encoded subscription parameters: https://checkout.tributary.so/subscribe/{encoded_data} Encoded data includes: - `tm`: Token mint (defaults to USDC: `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`) - `r`: Recipient public key (base58) - `g`: Gateway public key (base58) - `a`: Total amount (calculated from line items) - `ar`: Auto-renew flag - `mr`: Maximum renewals (default: "null" = unlimited) - `pf`: Payment frequency - `st`: Start time (default: "null" = immediate) - `tid`: Tracking ID - `li`: Line items (JSON array) ``` ### Technical Analysis Base64URL provides reversible encoding and does not provide confidentiality. Anyone who obtains a generated checkout URL can decode its subscription parameters, including the amount, recipient, renewal settings, tracking ID, and line-item descriptions. The Skill recommends tracking identifiers incorporating user and plan values, which can make decoded URLs customer-linkable. URLs are routinely retained in browser history, application logs, reverse-proxy logs, monitoring systems, analytics platforms, support tickets, screenshots, clipboard history, and shared messages. The documentation also does not state that the encoded payload is cryptographically signed or authenticated. If the checkout service relies only on decoded client-supplied fields, an attacker could attempt to modify parameters such as the recipient, amount, gateway, or renewal configuration. Whether such modification succeeds depends on server-side and on-chain validation not present in the audited project. ### Attack Path **Disclosure path:** 1. An application generates a checkout URL containing encoded subscription data. 2. The URL is recorded in browser history, logs, analytics, ...[truncated 1299 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace parameter-bearing URLs with short-lived, opaque server-side session identifiers. - Store authoritative checkout details on a trusted server and retrieve them only after validating the session. - If self-contained URLs are required, cryptographically authenticate the complete payload with a strong signature or authenticated-encryption scheme. - Reject altered, expired, replayed, or unsigned payloads. - Independently validate the token mint, gateway, recipient, amount, frequency, and renewal limits at checkout and on-chain. - Avoid placing customer IDs, email addresses, account names, or other personal data in tracking IDs. - Minimize line-item and memo data included in URLs. - Apply URL redaction to application, proxy, analytics, and monitoring logs. - Use strict referrer policies and prevent third-party resources from receiving checkout URL data. - Set short expiration periods and single-use protections for checkout sessions. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The skill documents conflicting checkout domains and base URL behavior, showing both `lando.tributary.so/#` and `checkout.tributary.so/subscribe/{encoded_data}` as the effective checkout destination. In a payments flow, domain confusion is security-relevant because integrators may redirect users to the wrong host, weaken origin validation, or normalize unsafe handling of payment URLs that could enable phishing or broken payment flows.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explains that subscription parameters are embedded in Base64URL-encoded checkout URLs and on-chain memo/tracking fields, but does not warn that these values are merely encoded, not secret, and may be logged, shared, cached, or exposed in browser history and analytics. Because tracking IDs, line items, and memo-related business data can reveal customer identities or transaction context, this omission creates meaningful privacy and integrity risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill encourages enabling `autoRenew` for recurring plans but does not require a prominent disclosure that this authorizes ongoing recurring charges. In a payment/subscription context, missing consent language is dangerous because users or downstream agents may set up renewals without clear authorization, creating financial harm, disputes, and compliance risk.

Intent-Code Divergence

Low
Confidence
87% confidence
Finding
The document says callers may provide a custom `memo`, but later states the on-chain memo is stored as a fixed `tributary:payment:{trackingId}` value. This inconsistency can cause developers to place sensitive or audit-relevant data in `memo` under false assumptions about what is actually recorded, undermining integrity, troubleshooting, and privacy expectations.

Static analysis

No suspicious patterns detected.