Back to skill

Security audit

The Agent Payment Rails Playbook

Security checks for vulnerabilities and agentic risk

Overview

This is a non-executing payment guide, but its runnable examples handle real credentials and payment actions with insufficient guardrails.

Review this as operational payment guidance, not just educational text. Use sandbox-only credentials, pin the gateway host, avoid putting payment tokens or personal emails in metadata, and add explicit human review before running any create_payment_intent, confirm_payment, wallet, webhook, or dispute examples against production systems.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:175
Finding
Bearer API credential can be transmitted to an attacker-controlled gateway<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 175–191 **Vulnerability Type**: Unvalidated credential destination **Risk Level**: High ### Vulnerable Code ```python GATEWAY_URL = os.environ.get("GREENHELIX_API_URL", "https://sandbox.greenhelix.net") class GreenHelixClient: """Client for the GreenHelix A2A Commerce Gateway.""" def __init__(self, api_key: str): self.api_key = api_key self.headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } def execute(self, tool: str, params: dict[str, Any]) -> dict: """Execute a single tool via the GreenHelix REST API.""" response = requests.post( f"{GATEWAY_URL}/v1", headers=self.headers, json={"tool": tool, "input": params}, timeout=30, ) ``` ### Technical Analysis The destination receiving the `Authorization` bearer credential is controlled entirely by the `GREENHELIX_API_URL` environment variable. The example does not validate the URL scheme, hostname, port, or redirect behavior before attaching the credential. Environment variables may be modified by a compromised deployment configuration, malicious wrapper, poisoned CI/CD configuration, or another process with control over how the application is launched. An attacker could set the variable to an arbitrary HTTP or HTTPS endpoint and capture the GreenHelix API key when the client performs its next operation. The client also does not explicitly disable redirects. Although common HTTP clients generally remove authorization headers during many cross-host redirects, relying on library-specific redirect behavior is insufficient protection for a payment client. ### Attack Path 1. An attacker obtains control over the application’s environment or deployment configuration. 2. The attacker sets `GREENHELIX_API_URL` to an endpoint under their control. 3. A user initializes `GreenHelixCl ...[truncated 1203 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the gateway to an explicit set of approved HTTPS origins rather than accepting an unrestricted URL from the environment. - If endpoint configuration is required, parse it and enforce: - The `https` scheme. - An exact allowlist of GreenHelix hostnames. - Approved ports only. - No embedded user information. - No unexpected path, query, or fragment components. - Disable redirects for credential-bearing requests or revalidate every redirect destination before following it. - Use separate, narrowly scoped credentials for sandbox and production. - Restrict payment keys to only the tools required by the application. - Rotate the credential immediately if it may have been sent to an untrusted endpoint. - Keep credentials in a dedicated secret manager and prevent untrusted launch wrappers or deployment inputs from controlling security-sensitive endpoint configuration. - Add automated tests confirming that credentials are never attached to requests for unapproved origins. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:419
Finding
Reusable delegated payment token is copied into generic transaction metadata<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 419–438 **Vulnerability Type**: Sensitive payment token exposure through metadata **Risk Level**: High ### Vulnerable Code ```python # Step 2: Create a payment intent with ACP/card rail metadata intent = client.execute("create_payment_intent", { "agent_id": agent_id, "wallet_id": wallet_id, "amount": max_amount, "currency": "USD", "payment_method": "card", "metadata": { "protocol": "acp", "spt_token": spt_token, "merchant_url": merchant_product_url, "rail": "stripe_acp", } }) # Step 3: Confirm the payment (Stripe processes via SPT) confirmation = client.execute("confirm_payment", { "payment_intent_id": intent["payment_intent_id"], "payment_token": spt_token, }) ``` ### Technical Analysis Passing the Shared Payment Token through the dedicated `payment_token` field during confirmation may be necessary for payment processing. Copying the same reusable credential into generic `metadata` is not necessary for the declared functionality. Metadata is commonly included in transaction histories, audit records, analytics systems, support exports, event streams, and application logs. The guide expressly uses GreenHelix to provide logging and audit trails, increasing the likelihood that metadata receives broader access and longer retention than dedicated secret-bearing payment fields. If the SPT remains valid and is not strictly one-time, audience-bound, and merchant-bound, a reader of this metadata may be able to replay it within its delegated authorization scope. ### Attack Path 1. A user follows the ACP purchase example with a valid SPT. 2. `create_payment_intent` stores or processes the SPT as ordinary metadata. 3. The metadata is propagated to an audit log, transaction-history response, analytics platform, support export, event stream, or operator interface. 4. A user or service with access to that secondary system obtains ...[truncated 1133 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `spt_token` from the `metadata` object entirely. - Transmit the SPT only through a dedicated secret-bearing field to the intended payment processor. - Ensure payment tokens are automatically redacted from: - Application and HTTP logs. - Traces and error reports. - Audit records. - Event streams. - Support tooling. - Analytics and data-warehouse exports. - Enforce short expiration periods and one-time use. - Cryptographically bind each token to the intended merchant, amount ceiling, currency, audience, payment intent, and authorized operation. - Reject replay attempts and invalidate the token immediately after successful confirmation. - Apply field-level encryption if a token must briefly be retained. - Restrict access to payment-secret fields separately from ordinary transaction metadata. - Add automated secret-scanning tests for metadata and audit payloads. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:832
Finding
Human principal email is unnecessarily duplicated in broadly retrievable identity claims<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 832–889 **Vulnerability Type**: Excessive personal-data disclosure and retention **Risk Level**: Medium ### Vulnerable Code ```python # Step 1: Register the agent identity registration = client.execute("register_agent", { "agent_id": agent_id, "display_name": display_name, "organization": organization, "capabilities": capabilities, "metadata": { "human_principal": human_principal_email, "framework": "custom", "version": "1.0.0", "eu_ai_act_disclosure": True, } }) # Step 3: Build a claim chain linking agent -> org -> human principal claim_chain = client.execute("build_claim_chain", { "agent_id": agent_id, "claims": [ { "claim_type": "deployed_by", "subject": agent_id, "issuer": organization, "value": organization, }, { "claim_type": "authorized_by", "subject": agent_id, "issuer": organization, "value": human_principal_email, }, { "claim_type": "capability", "subject": agent_id, "issuer": organization, "value": ",".join(capabilities), }, { "claim_type": "eu_ai_act_article_50", "subject": agent_id, "issuer": organization, "value": json.dumps({ "is_ai_system": True, "deployer": organization, "principal": human_principal_email, "purpose": "autonomous_commerce", }), } ], }) ``` ### Technical Analysis The example transmits the human principal’s direct email address to GreenHelix in three places: 1. Agent-registration metadata. 2. The `authorized_by` claim. 3. The serialized EU AI Act disclosure claim. The same guide later retrieves claim chains through `get_claim_chains` when verifying counterpartie ...[truncated 2122 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the direct email address with a pseudonymous, organization-issued principal identifier. - Use a verifiable credential that proves authorization without disclosing the underlying identity to every counterparty. - Apply selective disclosure so the principal’s identity is revealed only to an authorized verifier when legally or operationally required. - Do not duplicate personal identifiers in both metadata and multiple claim values. - Separate public compliance claims from restricted identity records. - Encrypt restricted identity attributes and apply field-level access controls. - Record and audit every access to principal identity data. - Define jurisdiction- and purpose-specific retention periods rather than applying a blanket retention rule. - Support revocation, correction, and deletion where legally permitted. - Document the legal basis and necessity for collecting the principal identifier. - Ensure counterparty verification returns only a boolean authorization result or pseudonymous reference unless additional disclosure is required. ]]>
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 (8)

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The introductory notice says all examples use the sandbox and that no API key is required, implying low-friction educational access. However, the documented client and curl examples later require `GREENHELIX_API_KEY` authorization headers and the manifest declares multiple credentials, so the actual demonstrated behavior depends on privileged credentials rather than unauthenticated sandbox use.

External Transmission

Medium
Category
Data Exfiltration
Content
Six protocols now compete to define how AI agents pay for things. On April 2, 2026, x402 joined the Linux Foundation with backing from Google, Stripe, AWS, and Visa. Two weeks earlier, Stripe launched its Model Provider Payments (MPP) suite. OpenAI's Agentic Commerce Protocol (ACP) powers checkout inside ChatGPT for Etsy and Shopify merchants. Google and Shopify's Universal Commerce Protocol (UCP) is in production. Visa's Trusted Agent Protocol (AP2/TAP) introduces Know Your Agent compliance for the first time. And ERC-8183 handles on-chain escrow for agent jobs on Ethereum mainnet.
Each protocol solves a different slice of the problem. None solves the whole thing. The agent builder who ships a payment integration today faces a brutal question: which protocols do I wire together, and how?
This playbook answers that question with production code. Every chapter contains working Python examples against the GreenHelix A2A Commerce Gateway -- 128 tools accessible at `https://api.greenhelix.net/v1` via a single the REST API (`POST /v1/{tool}`) endpoint. By the end, you will have a multi-rail payment system that routes micropayments over stablecoin rails and high-value transactions over card rails, with spending controls, KYA compliance, dispute resolution, and production monitoring. All of it tested against the live gateway.

## What You'll Learn
- Chapter 1: The Agentic Payment Stack: Why 6 Protocols, Not 1
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Six protocols now compete to define how AI agents pay for things. On April 2, 2026, x402 joined the Linux Foundation with backing from Google, Stripe, AWS, and Visa. Two weeks earlier, Stripe launched its Model Provider Payments (MPP) suite. OpenAI's Agentic Commerce Protocol (ACP) powers checkout inside ChatGPT for Etsy and Shopify merchants. Google and Shopify's Universal Commerce Protocol (UCP) is in production. Visa's Trusted Agent Protocol (AP2/TAP) introduces Know Your Agent compliance for the first time. And ERC-8183 handles on-chain escrow for agent jobs on Ethereum mainnet.
Each protocol solves a different slice of the problem. None solves the whole thing. The agent builder who ships a payment integration today faces a brutal question: which protocols do I wire together, and how?
This playbook answers that question with production code. Every chapter contains working Python examples against the GreenHelix A2A Commerce Gateway -- 128 tools accessible at `https://api.greenhelix.net/v1` via a single the REST API (`POST /v1/{tool}`) endpoint. By the end, you will have a multi-rail payment system that routes micropayments over stablecoin rails and high-value transactions over card rails, with spending controls, KYA compliance, dispute resolution, and production monitoring. All of it tested against the live gateway.

## What You'll Learn
- Chapter 1: The Agentic Payment Stack: Why 6 Protocols, Not 1
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The guide repeatedly presents payment creation and confirmation flows against live or live-like endpoints without strong guardrails warning that running them outside sandbox can trigger real financial actions. In a payment skill, this context increases risk because users may paste examples directly and unintentionally initiate charges, fund transfers, or settlement operations.

External Transmission

Medium
Category
Data Exfiltration
Content
def execute(self, tool: str, params: dict[str, Any]) -> dict:
        """Execute a single tool via the GreenHelix REST API."""
        response = requests.post(
            f"{GATEWAY_URL}/v1",
            headers=self.headers,
            json={"tool": tool, "input": params},
Confidence
80% confidence
Finding
The code transmits user-supplied payment and identity data, along with bearer credentials, to an external service. External transmission is expected for a payment gateway client, but the snippet omits basic hardening such as allowlisting hosts, validating destination configuration, and warning that secrets and transaction metadata leave the local environment.

External Transmission

Medium
Category
Data Exfiltration
Content
print(f"Received {len(market_data['ticks'])} market ticks")
```

### Verifying Payments with curl

For quick testing, the same flow works from the command line:
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
}' | jq .

# Step 3: Confirm and get receipt
RECEIPT=$(curl -s -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $GREENHELIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
84% confidence
Finding
This example sends an authorization bearer token to an external endpoint and retrieves a payment receipt, creating a realistic path for accidental secret use and unintended financial operations if copied blindly. In the context of a payments playbook, executable shell snippets with real request structure materially raise operational risk even if the intent is instructional.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
The notice frames the content as non-executing illustrative material, while later sections explicitly describe the snippets as working code against live or production endpoints. That is not just incomplete documentation; it creates conflicting expectations about whether the examples are inert reference material or operational code intended to perform real payment actions when run.

Static analysis

No suspicious patterns detected.