Back to skill

Security audit

PayTrigo (OpenClawBot, Base/USDC)

Security checks for vulnerabilities and agentic risk

Overview

This payment skill is mostly coherent, but it embeds live payment API keys and can sign blockchain transactions with a user's wallet without enough validation or confirmation.

Install only after the publisher removes and rotates the embedded PayTrigo keys, requires user- or deployment-provided secrets, adds decoded transaction validation and explicit confirmation for bot payments, stops accepting raw private keys/passphrases on the command line, and pins dependencies with a lockfile. Use a dedicated low-balance wallet if testing.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/paytrigo.mjs:7
Finding

Hard-Coded Live PayTrigo API Credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/moltbot-bot-flow.mjs:154
Finding

Unvalidated Signing of API-Supplied Blockchain Transactions

Content
View full analysis
{ const tx = await wallet.sendTransaction({ to: step.to, data: step.data, value: BigInt(step.value ?? '0'), }); console.log(`[${label}] txHash: ${tx.hash}`); const receipt = await tx.wait(); console.log(`[${label}] confirmed in block ${receipt.blockNumber}`); return tx.hash; }; ``` ```js const intent = await request( 'GET', `/v1/invoices/${invoice.invoiceId}/intent?chain=base&token=usdc`, undefined, intentHeaders, ); const provider = new JsonRpcProvider(rpcUrl); const wallet = (await getWallet()).connect(provider); if (!skipApprove && intent.steps?.approve) { await sendStep(wallet, intent.steps.approve, 'approve'); } const payTxHash = await sendStep(wallet, intent.steps.pay, 'pay'); ``` ### Technical Analysis The bot retrieves `approve` and `pay` transaction objects from a remote API and passes their `to`, `data`, and `value` fields directly to `wallet.sendTransaction()`. Before signing, the code does not validate: - The RPC network or expected Base chain ID. - The destination against known USDC and PayTrigo router addresses. - The ABI function selector. - The token covered by an approval. - The approval spender or allowance amount. - The expected payment recipient. - The payment amount encoded in calldata. - Whether native currency value must be zero. - Whether the returned transaction corresponds to the invoice that was created. TLS reduces ordinary interception risk but does not make remotely supplied calldata intrinsically safe. A compromised API, API account, DNS/TLS path, or upstream backend could return arbitrary transaction data. A malicious approval could grant an attacker an unlimited allowance, whil ...[truncated 1783 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/moltbot-human-flow.mjs:156
Finding

Checkout Authorization Tokens Disclosed Through Standard Output

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/moltbot-bot-flow.mjs:98
Finding

Private Keys and Wallet Passphrases Accepted Through Process Arguments

Content
View full analysis
{ if (args['passphrase-file']) { const value = (await readRequiredFile(args['passphrase-file'])).trimEnd(); if (!value) { fail('Passphrase file is empty.'); } return value; } if (args.passphrase) { return args.passphrase; } fail('Missing --passphrase or --passphrase-file (required to decrypt wallet)'); return ''; }; const getWallet = async () => { if (args.pk) { return new Wallet(args.pk); } const storeDir = args['store-dir'] ?? DEFAULT_STORE_DIR; const walletFile = args['wallet-file'] ?? resolve(storeDir, DEFAULT_WALLET_FILE); const walletJson = await readOptionalFile(walletFile); if (!walletJson) { fail('Missing --pk (or set --wallet-file / .openclawbot/wallet.json)'); } const passphrase = await getPassphrase(); return Wallet.fromEncryptedJson(walletJson, passphrase); }; ``` The unsafe form is explicitly documented: ```bash node scripts/moltbot-bot-flow.mjs bot --amount 0.001 --recipient 0xYourWallet... --pk 0xPRIVATE_KEY ``` The wallet setup script also accepts a passphrase from the argument list: ```js const getPassphrase = async () => { if (args['passphrase-file']) { const content = await readFileText(args['passphrase-file']); const trimmed = content.trimEnd(); if (!trimmed) { fail('Passphrase file is empty.'); } return trimmed; } if (args.passphrase) { return args.passphrase; } fail('Missing --passphrase or --passphrase-file'); return ''; }; ``` ### Technical Analysis Private keys and wallet-decryption passphrases can be supplied as `--pk` and `--passphrase` command-line arguments. Depending on ...[truncated 1657 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
package.json:5
Finding

Non-Reproducible Dependency Installation Without a Lockfile

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (20)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly states that a platform API key is embedded in the helper script and promotes 'no-setup' immediate use. Embedding live credentials in distributable skill content is dangerous because any user or downstream agent can extract and abuse the key to create invoices, misuse platform resources, or impersonate legitimate payment activity.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill normalizes passing private keys on the command line and handling encrypted wallets/passphrase files without prominent safety guidance. Command-line private keys, local plaintext key files, and passphrase files are commonly exposed through shell history, process lists, logs, backups, or weak filesystem permissions, creating a realistic path to wallet compromise and fund theft.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script hard-codes a live PayTrigo secret key directly in source, which exposes reusable production credentials to anyone who can read the file, logs, repository history, or packaged skill contents. Because this skill is explicitly designed to create payment invoices, the embedded key enables unauthorized API use, invoice creation, abuse of the merchant account, and possible downstream financial or operational damage.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

After obtaining remote transaction instructions, the script immediately sends on-chain approve and pay transactions with the user's wallet and waits for confirmation, without any interactive confirmation or final review of recipient, amount, contract target, or calldata. In a payment skill context, this is especially dangerous because a mistaken invocation, compromised API response, or mis-specified recipient can directly cause irreversible loss of funds or unsafe token approvals.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script embeds a live PayTrigo secret key directly in source code and uses it to create invoices against a production payment API. Any user who can read the skill, logs, repository, or packaged artifact can extract the credential and create or query payment objects on the associated account, leading to unauthorized API use, billing abuse, and broader account compromise.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A hard-coded live API credential in source code is a direct secret exposure vulnerability. Because this skill is specifically designed to create and verify PayTrigo payments, the exposed key is especially dangerous: anyone with access to the script can invoke privileged payment API operations in the production environment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script embeds and actively uses a live PayTrigo secret key, which gives anyone with access to the skill source immediate authenticated access to the payment API. In a payment-creation helper, this is especially dangerous because the key can be reused outside the intended workflow to create, inspect, or manipulate payment-related resources, and hard-coding prevents proper key rotation and scope control.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly instructs users to pass a raw private key on the command line (--pk 0xPRIVATE_KEY). Command-line secrets are commonly exposed through shell history, process listings, terminal logging, CI logs, and remote session tooling, which can lead to full compromise of the payer wallet and theft of funds. In this skill’s context, the secret is a blockchain private key, so exposure is especially dangerous because transactions are irreversible.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 35)May include surrounding context.

1) Create a passphrase file (local only)

bash
echo "use-a-strong-passphrase" > passphrase.txt
chmod 600 passphrase.txt

2) Create a wallet (optionally set it as recipient)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises and instructs use of network and shell-capable scripts, but does not declare any tool scope or permission boundaries. That omission increases the chance an agent will run commands or make outbound requests without explicit user awareness, which is especially risky in a payment-handling skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The request helper sends invoice creation and payment-intent submission data to an external API, including recipientAddress, metadata, txHash, and payerAddress. The script contains no visible disclosure that these details will be transmitted to a third-party service, beyond the implementation itself.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The advertised capability includes payment verification, but the implemented flow only creates invoices, retrieves payment intents, signs blockchain transactions, and submits payment execution. This mismatch is security-relevant because users or orchestrators may invoke the skill expecting a read-only verification action, while the code performs state-changing financial operations that can spend funds.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script performs a real payment-related API action as soon as the human command is run, creating a live invoice before any explicit confirmation prompt or strong warning. In an agent-skill context, this increases the risk of accidental or automated payment operations being triggered by misunderstood instructions, unsafe defaults, or adversarial task inputs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The CLI accepts passphrases directly via --passphrase and private keys via --pk, which can expose secrets through shell history, process listings, terminal logging, CI job output, and agent telemetry. In an agent-driven payment skill, this is especially risky because wallet credentials protect real funds and may be handled in automated environments where command invocations are widely observable.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes a skill for creating or verifying PayTrigo payments on Base/USDC without webhooks, which suggests payment operations. This script instead creates new Ethereum wallets, imports private keys, encrypts them, and writes wallet, address, passphrase-derived, and recipient state to local files, which is a separate wallet provisioning/storage capability not described in the manifest.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Creating random wallets and importing raw private keys are powerful key-management capabilities distinct from creating or verifying payments. A payment-focused skill may need to use an existing wallet, but provisioning and importing sensitive key material is not obviously required by the manifest's narrowly stated purpose.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script's messaging implies the API key should come from PAYTRIGO_API_KEY, but the actual code always uses the embedded default key instead. This mismatch can mislead operators into thinking they control authentication through environment configuration when in reality the exposed built-in credential is always used, undermining secret management and incident response.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script creates invoices and submits payment intent/status requests to a remote payment API, transmitting recipient addresses, transaction hashes, payer addresses, and metadata. Although these operations are central to the tool, the file provides no explicit user-facing warning or confirmation that payment-related data will be sent to an external service.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency version for ethers is specified with a caret range, which permits automatic installation of newer minor and patch releases. This can introduce supply-chain risk or unexpected behavior changes if a compromised or incompatible release is published, especially in a payment-related skill that interacts with Base/USDC transactions.

Content

Scanner excerpt · package.json (reported line 6)May include surrounding context.

json
"private": true,
  "type": "module",
  "dependencies": {
    "ethers": "^6.0.0"
  }
}

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

When --recipient is not supplied, the script automatically reads a recipient address from .openclawbot/recipient.txt or another provided file path. This local data access is not described in any warning or explanatory comment, which can surprise users who do not expect file-based input to be used implicitly.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/moltbot-bot-flow.mjs:9

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/moltbot-human-flow.mjs:8

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/paytrigo.mjs:8