Back to skill

Security audit

MoonPay Commerce (Helio) Accept Crypto Payments

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it handles merchant payment credentials in ways that need careful review before installation.

Review this before installing on any shared, managed, recorded, or multi-user machine. The skill can create and modify real payment links using your MoonPay Commerce credentials, so confirm amounts, currencies, pay-link IDs, and wallet selection before running commands. Store the config with strict owner-only permissions, avoid running setup while screen sharing or recording, and rotate the API secret if it may have appeared in terminal output or process logs.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.sh:112
Finding

API Secret Is Entered with Terminal Echo Enabled

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.sh:119
Finding

Bearer Credential Is Exposed Through curl Process Arguments

Content
View full analysis
Remediation
View remediation
"$header_file" curl --config "$header_file" -s "$BASE/wallet/all?apiKey=$HELIO_API_KEY" rm -f "$header_file" trap - EXIT ``` Further hardening: 1. Prefer a file-descriptor-based curl configuration where supported, avoiding a persistent temporary pathname. 2. If a temporary file is necessary, enforce mode `600`, verify ownership, and remove it using a reliable `trap`. 3. Do not enable shell tracing with `set -x` around credential handling. 4. Ensure CI systems, command wrappers, and observability agents redact authorization headers. 5. Consider short-lived or narrowly scoped API credentials if supported by the service. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.sh:39
Finding

Credential Loader Accepts Group-Readable or Group-Writable Configuration Files

Content
View full analysis
/dev/null 2>&1; then perms=$(stat -c '%a' "$cfg") # GNU else perms=$(stat -f '%A' "$cfg") # BSD/macOS fi local other="${perms: -1}" if [[ "$other" != "0" ]]; then echo "WARNING: Config $cfg has unsafe permissions ($perms) — skipping" >&2 echo " Fix with: chmod 600 $cfg" >&2 return 1 fi ``` ### Technical Analysis The loader examines only the final permission digit, which represents permissions for “other.” It does not reject group permissions. Consequently, modes such as the following are accepted: - `640`: group-readable - `660`: group-readable and group-writable - `620`: group-writable - `670`: broad group access This is inconsistent with the documented requirement that the configuration use mode `600`. Although setup calls `chmod 600` after writing a new file, a pre-existing or subsequently modified file with unsafe group permissions will still be loaded. Group-read access exposes `HELIO_API_SECRET`. Group-write access additionally permits modification of API credentials and wallet identifiers. The loader avoids shell evaluation and only accepts whitelisted keys, which reduces code-execution risk, but it does not prevent credential theft or configuration substitution. ### Attack Path Credential disclosure path: 1. The configuration file has mode `640` or another group-readable mode. 2. A second local account belongs to the file's group. 3. The loader accepts the file because the “other” permission digit is `0`. 4. The second account reads `HELIO_API_SECRET` directly from the file. 5. The attacker reuses the credentials against the MoonPay Commerce API. Co ...[truncated 849 chars]
Remediation
View remediation
/dev/null 2>&1; then perms=$(stat -c '%a' "$cfg") else perms=$(stat -f '%Lp' "$cfg") fi if [[ "$perms" != "600" ]]; then echo "WARNING: Config $cfg must have mode 600; found $perms — skipping" >&2 return 1 fi ``` Additional controls: 1. Set `umask 077` before creating the configuration directory or file. 2. Require the configuration directory to be owned by the current user and use mode `700`. 3. Continue verifying that the file is owned by the current user. 4. Reject symbolic links or use no-follow file-opening behavior to reduce replacement and race risks. 5. Write credentials atomically to a protected temporary file in the same directory, set mode `600`, and then rename it into place. 6. Apply identical validation in both `setup.sh` and `helio.sh` to avoid divergent security behavior. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/setup.sh:68
Finding

Status Command Unnecessarily Discloses API Secret Fragments

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (30)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill clearly instructs use of shell commands and external network access, but it does not declare an explicit tool scope such as allowed-tools or permissions. That weakens runtime safety boundaries and can let an agent invoke shell/network capabilities more broadly than reviewers or the platform expect.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
---
name: mpc-accept-crypto-payments
description: Accept crypto payments on Solana via MoonPay Commerce (formerly Helio). Create Pay Links, generate checkout URLs, check transactions, and list supported currencies. Use when the user wants to accept crypto payments, create payment links, charge for products/services with crypto, or query payment transactions. Requires a MoonPay Commerce account with API key and secret.
metadata:
  openclaw:
    requires:

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill is designed to create persistent payment artifacts such as pay links and associated charges, which can outlive the current session and have financial consequences. In a payments context this is expected functionality, but it is still security-relevant because accidental or unauthorized creation of links can lead to fraud, confusion, or operational issues.

Content

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

curl -s https://api.hel.io/v1/currency | jq '.[].symbol'

text

### Create a Pay Link
```bash
curl -s -X POST "https://api.hel.io/v1/paylink/create/api-key?apiKey=$HELIO_API_KEY" \
  -H "Authorization: Bearer $HELIO_API_SECRET" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The pay-link creation example performs authenticated outbound transmission and includes credential material in a way that may be captured by logs or telemetry. Because the skill handles payment operations, this is contextually expected, but compromise of these credentials could enable unauthorized payment-link creation or merchant account abuse.

Content

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

Create a Pay Link

bash
curl -s -X POST "https://api.hel.io/v1/paylink/create/api-key?apiKey=$HELIO_API_KEY" \
  -H "Authorization: Bearer $HELIO_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The pay-link creation example performs authenticated outbound transmission and includes credential material in a way that may be captured by logs or telemetry. Because the skill handles payment operations, this is contextually expected, but compromise of these credentials could enable unauthorized payment-link creation or merchant account abuse.

Content

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

Create a Pay Link

bash
curl -s -X POST "https://api.hel.io/v1/paylink/create/api-key?apiKey=$HELIO_API_KEY" \
  -H "Authorization: Bearer $HELIO_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This charge-creation request sends authenticated data to the external API and again exposes the API key in the URL. While this network access is core to the skill's function, the credential handling approach raises the risk of secret disclosure and unauthorized transaction-related actions if logs are exposed.

Content

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

Create a Charge (Checkout URL)

bash
curl -s -X POST "https://api.hel.io/v1/charge/api-key?apiKey=$HELIO_API_KEY" \
  -H "Authorization: Bearer $HELIO_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"paymentRequestId": "<PAYLINK_ID>"}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The transaction-check request is an authenticated external call using sensitive credentials, with the API key in the URL. Even read-oriented calls can leak account data and credentials if request details are logged or shared unintentionally.

Content

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

Check Transactions

bash
curl -s "https://api.hel.io/v1/paylink/<PAYLINK_ID>/transactions?apiKey=$HELIO_API_KEY" \
  -H "Authorization: Bearer $HELIO_API_SECRET"

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This authenticated PATCH request can change pay-link state and exposes the API key in the request URL. If the credentials leak, an attacker could disable or re-enable payment links and disrupt payment operations.

Content

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

Disable / Enable a Pay Link

bash
curl -s -X PATCH "https://api.hel.io/v1/paylink/<PAYLINK_ID>/disable?apiKey=$HELIO_API_KEY&disabled=true" \
  -H "Authorization: Bearer $HELIO_API_SECRET"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation explicitly instructs users to send the API secret as a bearer token and the API key in the query string, but it does not include any guidance on securely storing, redacting, or avoiding exposure of those credentials. In a payment-processing skill, this omission increases the chance that implementers will log secrets, paste them into shared traces, or otherwise mishandle credentials that grant access to financial operations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/helio.sh (reported line 152)May include surrounding context.

sh
echo "Creating Pay Link: $name — $amount $symbol ($price base units, currency=$currency_id, swap=on)"

    result=$(curl -s -X POST "$BASE/paylink/create/api-key?apiKey=$HELIO_API_KEY" \
      -H "Authorization: Bearer $HELIO_API_SECRET" \
      -H "Content-Type: application/json" \
      -d "$(jq -n \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This shell script sends authenticated requests to the Helio API using both an API key and bearer secret, but it does not include any user-facing warning about transmitting credentials and payment-link metadata to a third-party network service. While the script logs the action being taken, the usage/help text does not disclose the privacy-sensitive external transmission behavior.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/helio.sh (reported line 194)May include surrounding context.

sh
check_auth

    echo "Creating charge for paylink $paylink_id..."
    result=$(curl -s -X POST "$BASE/charge/api-key?apiKey=$HELIO_API_KEY" \
      -H "Authorization: Bearer $HELIO_API_SECRET" \
      -H "Content-Type: application/json" \
      -d "$(jq -n --arg id "$paylink_id" '{paymentRequestId: $id}')")

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/helio.sh (reported line 247)May include surrounding context.

sh
Commands:
  currencies                             List Solana currencies (no auth needed)
  currency-id <SYMBOL>                   Get currency ID for a symbol
  create-paylink <name> <amount> <symbol>  Create a Pay Link
  charge <paylink-id>                    Create a checkout URL for payers
  transactions <paylink-id>              List transactions for a Pay Link
  disable <paylink-id>                   Disable a Pay Link

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 51)May include surrounding context.

md
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 55)May include surrounding context.

md
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 141)May include surrounding context.

md
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/api-reference.md (reported line 3)May include surrounding context.

md
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/api-reference.md (reported line 4)May include surrounding context.

md
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/api-reference.md (reported line 5)May include surrounding context.

md
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/helio.sh (reported line 18)May include surrounding context.

sh
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/setup.sh (reported line 14)May include surrounding context.

sh
CONFIG_DIR="$HOME/.mpc/helio"
CONFIG_FILE="$CONFIG_DIR/config"
BASE="https://api.hel.io/v1"

die() { echo "❌ $1" >&2; exit 1; }
ok()  { echo "✅ $1"; }

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/helio.sh (reported line 38)May include surrounding context.

sh
return 1
  fi

  # Reject world-readable or world-writable
  local perms
  if stat --version &>/dev/null 2>&1; then
    perms=$(stat -c '%a' "$cfg")  # GNU

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/setup.sh (reported line 36)May include surrounding context.

sh
return 1
  fi

  # Reject world-readable or world-writable
  local perms
  if stat --version &>/dev/null 2>&1; then
    perms=$(stat -c '%a' "$cfg")  # GNU

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/helio.sh (reported line 38)May include surrounding context.

sh
return 1
  fi

  # Reject world-readable or world-writable
  local perms
  if stat --version &>/dev/null 2>&1; then
    perms=$(stat -c '%a' "$cfg")  # GNU

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/setup.sh (reported line 36)May include surrounding context.

sh
return 1
  fi

  # Reject world-readable or world-writable
  local perms
  if stat --version &>/dev/null 2>&1; then
    perms=$(stat -c '%a' "$cfg")  # GNU

Static analysis

No suspicious patterns detected.