T09 · Insecure Skill Coding Practices
- Location
bin/create-wire-job-from-quote.mjs:19- Finding
Arbitrary Base URL Allows Sensitive Workflow Data to Be Redirected
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears purpose-built for Ghost/x402 payments, but it needs review because it handles real wallet signing keys and payment data with several under-scoped safety controls.
Install only in a trusted server runtime using a dedicated low-balance signer key, never pass the private key on the command line, keep it in protected secret storage, prefer dry-run first, restrict base URLs to trusted HTTPS Ghost endpoints, and review/pin the npm dependency graph before using this for real payments.
bin/create-wire-job-from-quote.mjs:19Arbitrary Base URL Allows Sensitive Workflow Data to Be Redirected
bin/call-x402.mjs:37Private Signing Keys Can Be Exposed Through Command-Line Arguments
package.json:16Payment and Signing Dependencies Are Not Reproducibly Pinned
The quickstart requires users to provide a raw private key via an environment variable but does not include any warning or handling guidance for sensitive credential storage. In a payment and on-chain transaction skill, this increases the risk that operators paste secrets into shell history, commit them to dotfiles, expose them in process listings, or reuse production keys unsafely, which could lead to wallet compromise and unauthorized fund transfers.
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
## Contents
- `openclaw.plugin.json` - plugin descriptor with local skill path
- `skills/openclaw-ghost-pay/SKILL.md` - skill instructions for OpenClaw
- `bin/get-payment-requirements.mjs` - MCP-based payment requirement lookup
- `bin/call-x402.mjs` - real `x402` client helper for merchant endpoints
- `bin/report-x402-settlement.mjs` - manual merchant-signed settlement report helper for GhostRank fallback/recovery
The README states that GHOST_SIGNER_PRIVATE_KEY is required for paid calls, but the safety warning is minimal and appears only later in the document. In a payment-signing skill, this can lead users to paste a hot private key into insecure places, misunderstand that real-value signatures will be produced, or run example commands against live merchant endpoints without appreciating custody and spending risk.
The skill requires access to a highly sensitive environment variable, GHOST_SIGNER_PRIVATE_KEY, but does not declare any explicit tool scope such as permissions or allowed-tools. That creates an unnecessary trust gap: an agent/runtime may expose environment access more broadly than intended, increasing the chance of secret misuse, accidental disclosure, or unauthorized paid transaction execution. The skill context makes this more dangerous because it is explicitly designed to perform real payment and settlement actions, so compromise of the signer key directly enables financial abuse.
The script accepts a signer private key from a CLI argument or environment variable and uses it to create a signer for payment-enabled requests. Although it checks for presence, there is no user-facing warning, comment, or prompt explaining that a sensitive credential is being consumed for signing/payment operations.
This code performs an outbound HTTP request using a user-provided URL and may send arbitrary headers and JSON body content, which can include user or system data. The script has validation and a dry-run mode, but it does not display any confirmation, warning, or explanatory comment before transmitting data.
This code sends wallet/address identifiers and principal amount to a remote HTTP endpoint via POST, which is a safety-relevant network transmission. The file includes neither a confirmation prompt nor any user-facing disclosure such as a comment, docstring, or log message explaining that these values will be sent off-box.
This code POSTs settlement telemetry including payerIdentity, optional payerAddress, paymentReference, requestId, and metadata to a remote endpoint. While the script name suggests reporting, there is no visible confirmation prompt, log message, or comment/docstring in this file warning that potentially sensitive payment-related data will be transmitted.
The script reads configuration from environment variables, including the remote base URL and timeout, and later uses that configuration to make a network call. There is no visible disclosure in this file that environment-provided settings may influence where user-supplied data is transmitted.
The dependency uses a caret range rather than an exact pinned version, which permits automatic installation of newer minor/patch releases. This weakens build reproducibility and increases supply-chain risk because a compromised or regressed upstream release could be pulled in without explicit review.
"wire:status": "node ./bin/get-wire-job-status.mjs"
},
"dependencies": {
"viem": "^2.21.0",
"x402": "^1.1.0",
"x402-fetch": "^1.1.0"
}
The x402 package is unpinned, so installs may resolve to different releases over time, making it impossible to guarantee which code is executed. In this skill's context, that is more concerning because the package is directly related to payment and x402 transaction flows, so upstream compromise or unintended behavior could affect real payment execution.
},
"dependencies": {
"viem": "^2.21.0",
"x402": "^1.1.0",
"x402-fetch": "^1.1.0"
}
}
There is a known advisory affecting some x402 versions, and because the manifest does not pin the package, the actual installed version cannot be verified as safe or vulnerable from this file alone. Given that this skill explicitly executes real x402 payment calls and settlement reporting, uncertainty around a payment SDK with a known advisory materially raises risk.
The x402-fetch dependency is specified with a caret range, allowing silent drift to newer releases at install time. This creates a software supply-chain exposure and reduces auditability, especially for code that performs external network and payment-related fetch operations.
"dependencies": {
"viem": "^2.21.0",
"x402": "^1.1.0",
"x402-fetch": "^1.1.0"
}
}
Detected: suspicious.exposed_secret_literal