Back to skill

Security audit

Agent-Ready Commerce: Retrofit Your APIs for AI Buyers

Security checks for vulnerabilities and agentic risk

Overview

This is a non-executable commerce guide, but it asks for high-value credentials and includes production-style payment examples without enough scoping safeguards.

Review before installing. Treat the examples as live-network, potentially state-changing payment code. Use only sandbox or test credentials, avoid providing Stripe keys or agent signing private keys unless a specific executable workflow truly needs them, and add endpoint allowlisting, dry-run modes, spending caps, and human confirmation before adapting the examples for production.

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

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:14
Finding

Unused High-Value Credentials Are Declared as Mandatory

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 14-23
Vulnerability Type: Excessive credential access and violation of least privilege
Risk Level: Medium

Vulnerable Code

yaml
credentials: [GREENHELIX_API_KEY, WALLET_ADDRESS, AGENT_SIGNING_KEY, STRIPE_API_KEY]
metadata:
  openclaw:
    requires:
      env:
        - GREENHELIX_API_KEY
        - WALLET_ADDRESS
        - AGENT_SIGNING_KEY
        - STRIPE_API_KEY
    primaryEnv: GREENHELIX_API_KEY

Technical Analysis

The Skill declares four credentials as required, including AGENT_SIGNING_KEY and STRIPE_API_KEY. The reviewed examples operationally reference GREENHELIX_API_KEY, but no operational use of AGENT_SIGNING_KEY or STRIPE_API_KEY was identified.

Requiring an Ed25519 signing key and a payment-processing credential for an educational, non-executable guide exceeds the minimum privileges necessary for its declared functionality. It also conflicts with the guide's statement that its sandbox can be used without an API key.

Even if the Skill itself does not directly exfiltrate these values, placing unnecessary high-value secrets in the Agent's environment increases the consequences of another compromised Skill, unsafe tool invocation, debug logging, environment disclosure, or prompt-driven access to process configuration.

Attack Path

  1. A user installs or configures the Skill.
  2. The Skill framework interprets the front matter and requests all four declared credentials.
  3. The signing and Stripe credentials become available in the Skill or Agent execution environment despite not being needed by the reviewed examples.
  4. A compromised component, unsafe diagnostic operation, or unrelated Skill with environment access reads the unnecessary credentials.
  5. The attacker uses the signing key to impersonate the associated agent or uses the Stripe key for operations permitted by its actual server-side scope.

...[truncated 556 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove AGENT_SIGNING_KEY, STRIPE_API_KEY, and WALLET_ADDRESS from the mandatory credentials and requires.env declarations unless executable examples actually need them.
  2. Require only GREENHELIX_API_KEY for authenticated GreenHelix examples.
  3. Make the API key optional when the sandbox genuinely supports unauthenticated access.
  4. Move payment and signing credentials into separate, opt-in integration guides with explicit scopes and threat warnings.
  5. Recommend restricted test credentials rather than production credentials.
  6. Document key rotation and revocation procedures.
  7. If Stripe integration is later added, use a narrowly restricted test-mode key and never expose it to client-side or general Agent contexts.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:118
Finding

Bearer Credential Can Be Sent to an Unrestricted Environment-Controlled Host

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 118-136
Vulnerability Type: Credential exfiltration through unvalidated endpoint configuration
Risk Level: High

Vulnerable Code

python
import requests
from typing import Any

GATEWAY_URL = os.environ.get("GREENHELIX_API_URL", "https://sandbox.greenhelix.net")

class CommerceClient:
    """Client for 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, input_data: dict[str, Any]) -> dict:
        """Execute a single tool on the gateway."""
        response = requests.post(
            f"{GATEWAY_URL}/v1",
            json={"tool": tool, "input": input_data},
            headers=self.headers,
            timeout=30,
        )
        response.raise_for_status()
        return response.json()

Equivalent endpoint and authorization patterns recur at lines 603-632, 1234-1249, and 1705-1749.

Technical Analysis

GREENHELIX_API_URL controls the complete origin to which the client sends its Authorization: Bearer header. The code does not validate the URL scheme, hostname, port, resolved address, or redirect destination before attaching the credential.

An attacker who can influence the process environment can replace the intended GreenHelix endpoint with an attacker-controlled HTTPS server. The next API operation then sends the bearer credential directly to that server.

The examples are embedded in a non-executable guide, so the vulnerability is triggered only if a user copies and runs the implementation. Nevertheless, the code is presented as production-oriented and can propagate the unsafe pattern into real deployments.

Attack Path

  1. The victim adopts the documented CommerceClient.

...[truncated 1273 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin authenticated requests to explicit approved origins, such as the documented GreenHelix production and sandbox hosts.
  2. Parse the configured URL and require:
    • HTTPS.
    • An exact allowlisted hostname.
    • No embedded user information.
    • An expected port.
    • No fragments or unexpected path prefixes.
  3. Do not attach authorization headers until origin validation succeeds.
  4. Disable redirects for authenticated API calls or validate every redirect target before forwarding credentials.
  5. Ensure authorization headers are never forwarded across origins.
  6. Prefer a deployment mode selector such as sandbox or production over a freely configurable URL.
  7. Use short-lived, narrowly scoped tokens and rotate any credential potentially exposed through prior use of this pattern.
  8. Apply the same correction to every duplicated GreenHelix client implementation in the document.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:1724
Finding

Agent Simulator Performs Unrestricted Requests to Caller- and Manifest-Controlled URLs

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 1724-1825
Vulnerability Type: Server-Side Request Forgery
Risk Level: Medium

Vulnerable Code

python
class AgentSimulator:
    """Simulate AI shopping agent behavior to test storefront readiness."""

    def __init__(
        self,
        api_key: str,
        storefront_url: str,
        service_query: str,
    ):
        self.api_key = api_key
        self.storefront_url = storefront_url
        self.service_query = service_query
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }
        self.results: list[TestResult] = []

    def _timed_get(self, url: str) -> tuple[Optional[dict], float]:
        """GET a URL and return (parsed_json, latency_ms)."""
        start = time.time()
        try:
            resp = requests.get(url, timeout=10)
            latency = (time.time() - start) * 1000
            if resp.status_code == 200:
                return resp.json(), latency
            return None, latency
        except Exception:
            return None, (time.time() - start) * 1000

    def test_manifest(self) -> TestResult:
        """Test: Can agents find .well-known/ai-plugin.json?"""
        url = f"{self.storefront_url}/.well-known/ai-plugin.json"
        data, latency = self._timed_get(url)

        if data and "name_for_model" in data and "api" in data:
            has_description = bool(data.get("description_for_model", ""))
            has_api_url = bool(data.get("api", {}).get("url", ""))
            score = 1.0 if (has_description and has_api_url) else 0.7
            result = TestResult(
                dimension="discoverability",
                test_name="ai_plugin_manifest",
                passed=True,
                score=score,
                latency_ms=latency,
                details=f"
...[truncated 3983 chars]
Remediation
View remediation

Remediation Suggestions

  1. Permit only HTTPS URLs.
  2. Apply an explicit approved-domain policy when the set of testable storefronts is known.
  3. Resolve hostnames and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
  4. Repeat destination validation for every redirect and limit the number of redirects; preferably disable redirects by default.
  5. Prevent DNS rebinding by connecting to the validated address while separately preserving and verifying the expected TLS hostname.
  6. Block nonstandard ports unless explicitly required.
  7. Run the simulator in an isolated network namespace with egress firewall rules that deny internal and metadata networks.
  8. Set strict connection and read timeouts, maximum response sizes, and accepted content types.
  9. Avoid returning raw internal responses or detailed connection errors to untrusted users.
  10. Apply the same URL validation to storefront_url, manifest api.url, product-search URLs, and checkout URLs used elsewhere in the simulator.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (15)

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 991)May include surrounding context.

md
"payment_protocols": ["ucp", "acp", "x402", "greenhelix_escrow"],
        "accepted_currencies": ["USD", "EUR", "USDC"],
    }
    return rules


# Generate pricing rules for catalog

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
AI shopping agents now influence over $67 billion in purchasing decisions. Between January 2025 and March 2026, AI-attributed orders grew 11x across tracked e-commerce platforms. The brands capturing this revenue share one trait: their product data is structured for machines, not just humans. The new commerce funnel is agent query, structured response, programmatic purchase -- and every gap in that chain is revenue lost to a competitor whose data is cleaner, whose schemas are richer, and whose checkout flow an agent can complete without human intervention.
This guide is the practitioner's manual for building agent-ready commerce infrastructure. Every chapter contains production Python code 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 an agent-discoverable storefront, structured product feeds with validation, multi-protocol checkout flows (UCP, ACP, x402), a GreenHelix marketplace listing with trust signals, escrow-protected payment flows, an agent discoverability test harness, and a 14-day sprint plan to ship all of it.
1. [The Agentic Commerce Shift](#chapter-1-the-agentic-commerce-shift)

## What You'll Learn

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
AI shopping agents now influence over $67 billion in purchasing decisions. Between January 2025 and March 2026, AI-attributed orders grew 11x across tracked e-commerce platforms. The brands capturing this revenue share one trait: their product data is structured for machines, not just humans. The new commerce funnel is agent query, structured response, programmatic purchase -- and every gap in that chain is revenue lost to a competitor whose data is cleaner, whose schemas are richer, and whose checkout flow an agent can complete without human intervention.
This guide is the practitioner's manual for building agent-ready commerce infrastructure. Every chapter contains production Python code 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 an agent-discoverable storefront, structured product feeds with validation, multi-protocol checkout flows (UCP, ACP, x402), a GreenHelix marketplace listing with trust signals, escrow-protected payment flows, an agent discoverability test harness, and a 14-day sprint plan to ship all of it.
1. [The Agentic Commerce Shift](#chapter-1-the-agentic-commerce-shift)

## What You'll Learn

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This example transmits bearer-authenticated data to an external GreenHelix endpoint via requests.post. While expected for an API client, it still represents external transmission of potentially sensitive inputs and credentials, and the surrounding guide encourages reuse of the code with real environment variables.

Content

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

md
def execute(self, tool: str, input_data: dict[str, Any]) -> dict:
        """Execute a single tool on the gateway."""
        response = requests.post(
            f"{GATEWAY_URL}/v1",
            json={"tool": tool, "input": input_data},
            headers=self.headers,

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This helper posts arbitrary tool inputs to the external gateway, enabling transmission of buyer IDs, payment metadata, and other operational data off-host. In context, the code is framed as reusable production logic, so users may run it with live credentials without appreciating the data-flow and side effects.

Content

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

md
def _ghx(self, tool: str, input_data: dict) -> dict:
        """Execute a GreenHelix tool."""
        resp = requests.post(
            f"{GATEWAY_URL}/v1",
            json={"tool": tool, "input": input_data},
            headers=self.headers,

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The ghx function sends authenticated JSON payloads to the GreenHelix gateway and is later used for wallet creation, deposits, registrations, and metrics submission. This is a real external transmission path with side effects, not just passive sample text, so copied usage can expose operational or financial data to a remote service.

Content

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

md
def ghx(tool: str, input_data: dict) -> dict:
    """Execute a GreenHelix tool."""
    resp = requests.post(
        f"{GATEWAY_URL}/v1",
        json={"tool": tool, "input": input_data},
        headers=headers,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The guide includes runnable examples that invoke state-changing financial and marketplace operations such as deposits, escrow creation, subscriptions, and service registration. Although labeled educational, the content repeatedly presents production-style code and does not consistently warn that running it outside the sandbox can trigger real transactions, balance changes, or persistent marketplace registrations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This duplicate ghx helper again establishes a generic authenticated exfiltration path to a third-party endpoint and is used in payment and dispute flows. In a guide containing many live transaction examples, the risk is not the existence of HTTP itself but the lack of strong safeguards around what gets sent and when.

Content

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

md
def ghx(tool: str, input_data: dict) -> dict:
    resp = requests.post(
        f"{GATEWAY_URL}/v1",
        json={"tool": tool, "input": input_data},
        headers=headers,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The ensure_funded example normalizes automatic wallet top-ups and directly calls deposit when balance is below a threshold. In a real environment this can cause unintended funding events or charges without explicit operator confirmation, especially if copied into automation or CI workflows.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The simulator's _ghx method sends service queries and authenticated requests to the external marketplace API. Even though this is framed as testing, it can leak internal storefront URLs, search intentions, and account-linked metadata to a third-party system.

Content

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

md
self.results: list[TestResult] = []

    def _ghx(self, tool: str, input_data: dict) -> dict:
        resp = requests.post(
            f"{GATEWAY_URL}/v1",
            json={"tool": tool, "input": input_data},
            headers=self.headers,

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

This test posts to the storefront's /products/search endpoint, which is an external transmission but to the user's own configured service rather than an unexpected third party. The risk is lower, yet it still can send test queries over the network and trigger logging or downstream processing.

Content

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

md
search_url = f"{self.storefront_url}/products/search"
        start = time.time()
        try:
            resp = requests.post(
                search_url,
                json={"query": "", "limit": 5},
                timeout=10,

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The checkout protocol test sends live requests to /checkout/initiate for multiple payment methods, which can trigger payment-session creation, escrows, or other remote side effects. As written, it normalizes running these checks without requiring a non-production environment or a no-op test mode.

Content

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

md
start = time.time()
        for protocol in protocols:
            try:
                resp = requests.post(
                    checkout_url,
                    json={
                        "items": [{"sku": "TEST-SKU", "quantity": 1}],

External Transmission

Medium
Category
Data Exfiltration
Confidence
81% confidence
Finding

The latency benchmark repeatedly posts search requests to a remote endpoint, creating measurable traffic and possible logging or rate-limit impact. This is legitimate test behavior, but the guide does not emphasize safe execution against staging or synthetic datasets.

Content

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

md
for _ in range(num_requests):
            start = time.time()
            try:
                requests.post(
                    search_url,
                    json={"query": "bearing", "limit": 5},
                    timeout=10,

External Transmission

Medium
Category
Data Exfiltration
Confidence
81% confidence
Finding

This verification helper sends search traffic to the configured base URL as part of storefront validation. The network action is expected, but it still transmits data externally and could hit production unintentionally if copied verbatim.

Content

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

md
# Layer 2: Product schemas (check search endpoint)
    try:
        resp = requests.post(
            f"{base_url}/products/search",
            json={"query": "", "limit": 1},
            timeout=5,

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This verification helper posts to /checkout/initiate for several protocols and treats 200/201/402 as success, but does not prevent creation of real payment sessions or escrow objects. In context, this is more dangerous than ordinary API testing because checkout endpoints are inherently stateful and financially sensitive.

Content

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

md
for protocol in protocols:
        try:
            resp = requests.post(
                f"{base_url}/checkout/initiate",
                json={
                    "items": [{"sku": "TEST-VERIFY", "quantity": 1}],

Static analysis

No suspicious patterns detected.