Back to skill

Security audit

Botcoin Miner

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent with BOTCOIN mining, but it gives an agent broad wallet and transaction authority without enough mandatory safeguards.

Install only after reviewing the wallet risks. Use a dedicated low-balance wallet, avoid passing private keys on command lines, disable raw token logging, pin reviewed skill versions, restrict Bankr API key IPs and permissions where possible, and require explicit confirmation plus decoded transaction details before any swap, bridge, approval, stake, claim, or receipt/vouch broadcast.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:268
Finding
Bearer Authentication Token Exposed Through Raw Response Logging<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 268-282 **Vulnerability Type**: Sensitive credential exposure through logging **Risk Level**: High ### Vulnerable Code Snippet ```markdown **Auth token reuse (critical):** - Perform nonce+verify once, then reuse token for all challenge/submit calls until it expires. - Do not run auth handshake inside the normal mining loop. - Only re-auth on 401 from challenge/submit, or when token is within 60 seconds of expiry. **Auth handshake rules:** - **Always** send `Authorization: Bearer <token>` on `GET /v1/challenge` and `POST /v1/submit` when auth is enabled. - Build sign/verify JSON with `jq --arg` — never use manual string interpolation of the multi-line message. - Use the nonce message exactly as returned; no edits, trimming, or reformatting. - Do not reuse an auth nonce — each handshake gets a fresh nonce from `/v1/auth/nonce`. - Log raw HTTP status and response body for `/v1/auth/nonce`, `/v1/auth/verify`, and `/v1/challenge` to classify failures quickly. ``` The authentication flow stores the token directly from the verification response: ```bash VERIFY_RESPONSE=$(curl -s -X POST "${COORDINATOR_URL:-https://coordinator.agentmoney.net}/v1/auth/verify" \ -H "Content-Type: application/json" \ -d "...") TOKEN=$(echo "$VERIFY_RESPONSE" | jq -r '.token') ``` ### Technical Analysis The Skill instructs the Agent to log the complete response body returned by `/v1/auth/verify`. That response contains the reusable bearer token later placed in the `Authorization` header for challenge and submission requests. Consequently, the token can be copied into terminal transcripts, CI logs, shell diagnostics, Agent telemetry, centralized logging systems, or other storage with a broader audience and longer retention period than the token itself requires. The instruction conflicts with least-privilege credential handling because troubleshooting only requires status codes and sanitized error fields, n ...[truncated 1359 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the instruction to log raw response bodies from authentication endpoints. - Log only the HTTP status, request correlation ID, sanitized error code, and a redacted error message. - Explicitly replace `.token`, `.signature`, authorization headers, wallet API keys, and nonce messages with `[REDACTED]` before diagnostic output. - Keep bearer tokens in memory where possible and avoid shell tracing while they are present. - Disable `set -x` around authentication operations and ensure Agent or CI telemetry cannot capture environment variables or command output. - Apply restrictive permissions and short retention periods to any unavoidable authentication logs. - Prefer short-lived, narrowly scoped tokens and provide a revocation mechanism for suspected exposure. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:169
Finding
Opaque Coordinator-Supplied Transaction Calldata Is Executed Without Mandatory Local Validation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 169-201 **Vulnerability Type**: Execution of mutable remote transaction payloads **Risk Level**: Critical ### Vulnerable Code Snippet ```bash # Step 1: Get approve transaction (amount in base units) curl -s "${COORDINATOR_URL:-https://coordinator.agentmoney.net}/v1/stake-approve-calldata?amount=5000000000000000000000000" # Step 2: Get stake transaction curl -s "${COORDINATOR_URL:-https://coordinator.agentmoney.net}/v1/stake-calldata?amount=5000000000000000000000000" ``` ```markdown Each endpoint returns `{ "transaction": { "to": "...", "chainId": 8453, "value": "0", "data": "0x..." } }`. ``` ```bash curl -s -X POST https://api.bankr.bot/wallet/submit \ -H "Content-Type: application/json" \ -H "X-API-Key: $BANKR_API_KEY" \ -d '{ "transaction": { "to": "TRANSACTION_TO_FROM_RESPONSE", "chainId": TRANSACTION_CHAINID_FROM_RESPONSE, "value": "0", "data": "TRANSACTION_DATA_FROM_RESPONSE" }, "description": "Approve BOTCOIN for staking", "waitForConfirmation": true }' ``` ```markdown (Use the same submit pattern for stake, unstake, and withdraw — copy `to`, `chainId`, `value`, `data` from the coordinator response.) ``` ```bash cast send --rpc-url "$BASE_RPC_URL" --private-key "$MINER_PRIVATE_KEY" \ "$TX_TO" "$TX_DATA" ``` The same trust pattern is repeated for receipt and vouch transactions: ```markdown Broadcast each transaction — **no ABI encoding needed**, just copy `to`, `chainId`, `data` (and `gasLimit` if present) from the coordinator response. ``` ### Technical Analysis The Skill retrieves pre-encoded transaction objects from a mutable network service and directs the Agent to submit those objects through either a managed wallet API or a self-custodied wallet. There is no mandatory local step to: - Require Base chain ID `8453`. - Require `value` to be zero. - Match `to` against a strict operation-specific contract allowlist. - Deco ...[truncated 2544 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Treat every coordinator-provided transaction object as untrusted input. - Enforce `chainId == 8453` and an operation-specific `to` allowlist before signing. - Enforce `value == 0` unless a documented operation explicitly requires a bounded nonzero value. - Decode calldata with a locally pinned ABI and reject unknown function selectors. - For token approvals, verify: - The token contract is the documented BOTCOIN contract. - The spender is the documented staking contract. - The amount exactly matches the user-approved stake. - The amount is not an unlimited allowance unless the user separately authorizes that risk. - Locally reconstruct expected calldata and compare it byte-for-byte with the coordinator response. - Display the decoded target, method, parameters, token amount, spender, value, and chain to the user before each value-affecting transaction. - Require explicit confirmation for approvals, staking, unstaking, withdrawals, swaps, bridges, and claims. - Restrict or remove arbitrary `COORDINATOR_URL` overrides. If overrides are necessary, require an explicit trusted-host allowlist and pinned HTTPS certificate policy. - Use a dedicated low-balance mining wallet with no unrelated assets or permissions. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:197
Finding
Wallet Private Key Is Passed Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 197-201 **Vulnerability Type**: Private-key disclosure through process arguments **Risk Level**: Critical ### Vulnerable Code Snippet ```bash cast send --rpc-url "$BASE_RPC_URL" --private-key "$MINER_PRIVATE_KEY" \ "$TX_TO" "$TX_DATA" ``` The same pattern appears in other sensitive operations: ```bash SIGNATURE=$(cast wallet sign --private-key "$MINER_PRIVATE_KEY" "$MESSAGE") ``` ```bash cast send --rpc-url "$BASE_RPC_URL" --private-key "$MINER_PRIVATE_KEY" \ "$RECEIPT_TX_TO" "$RECEIPT_TX_DATA" cast send --rpc-url "$BASE_RPC_URL" --private-key "$MINER_PRIVATE_KEY" \ --gas-limit 100000 "$VOUCH_TX_TO" "$VOUCH_TX_DATA" ``` ```bash cast send --rpc-url "$BASE_RPC_URL" --private-key "$MINER_PRIVATE_KEY" \ "$CLAIM_TX_TO" "$CLAIM_TX_DATA" ``` ### Technical Analysis Shell expansion places the value of `MINER_PRIVATE_KEY` directly into the argument vector of the `cast` process. Depending on the operating system, runtime, and host configuration, command-line arguments may be observable through: - Process inspection utilities and `/proc` interfaces. - Process accounting or endpoint monitoring. - Shell tracing such as `set -x`. - CI/CD command logs. - Agent tool-call telemetry and execution transcripts. - Crash diagnostics or debugging systems. - Wrapper scripts that record invoked commands. An EVM private key is a permanent bearer credential. Unlike a short-lived coordinator token, it cannot be safely revoked without transferring assets and abandoning the corresponding wallet. Storing the key in an environment variable also creates exposure through process environments, but passing it into `--private-key` expands the exposure to command-line argument capture. ### Attack Path 1. The user sets `MINER_PRIVATE_KEY` and invokes one of the documented `cast` commands. 2. The shell expands the variable and passes the literal private key in the process argument vector. 3. A local user, mo ...[truncated 852 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove all examples that pass raw private keys through `--private-key`. - Prefer, in descending order: 1. Hardware wallets. 2. KMS or HSM-backed signers. 3. Dedicated remote signer services with transaction policies. 4. Encrypted keystore files protected by restrictive filesystem permissions. - Use Foundry account or keystore mechanisms that do not expose the private key in process arguments. - Require transaction confirmation and apply signer-level chain, destination, selector, value, and spending limits. - Disable shell tracing before any wallet operation and prevent command telemetry from recording sensitive signer parameters. - Use a dedicated mining wallet with only the minimum BOTCOIN and ETH required. - If the documented commands have already been run in a logged environment, treat the wallet as potentially compromised, rotate to a new key, transfer assets, and revoke outstanding token approvals. ]]>

T08 · Insecure Dependencies

Warning
Location
README.txt:5
Finding
Installation Instructions Use Unpinned Mutable Third-Party Sources<![CDATA[ ## Vulnerability Details **File Location**: `README.txt`, lines 5-16 **Vulnerability Type**: Unpinned dependency and Skill installation **Risk Level**: Medium ### Vulnerable Code Snippet ```markdown ## Install ```bash npx skills add botcoinmoney/botcoin-miner-skill ``` Works with Cursor, Claude Code, Windsurf, OpenClaw, and [40+ other agents](https://github.com/vercel-labs/skills#supported-agents). ## Prerequisites - **Bankr API key** — [bankr.bot/api](https://bankr.bot/api) - **Bankr skill** — `npx skills add BankrBot/openclaw-skills --skill bankr` ``` ### Technical Analysis Both installation commands resolve mutable external content without specifying a trusted release version, immutable commit hash, integrity digest, or signature. The `npx` invocation may also resolve the installer itself dynamically unless the executing environment already pins it. This creates multiple supply-chain trust points: - The package or executable selected by `npx`. - The upstream repository owner and account security. - The repository's mutable default branch. - Dependencies used by the installer. - The separately installed Bankr Skill. The README presents the Bankr Skill as a prerequisite even though `SKILL.md` describes it as optional. This unnecessarily expands the dependency and privilege boundary for users who could use the self-custody path without it. No evidence in the reviewed files establishes that the referenced upstream projects are currently malicious. The vulnerability is the absence of reproducible, integrity-verified installation instructions. ### Attack Path 1. An attacker compromises an upstream maintainer account, repository, package publication channel, or dependency. 2. The attacker changes content resolved by one of the unpinned installation commands. 3. A user runs the documented `npx skills add` command. 4. The installer retrieves the changed content rather than the version originally audited. 5. The Agent loads or executes the alt ...[truncated 817 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the Skill installer to an explicit trusted version. - Pin repository-based Skills to immutable commit hashes rather than mutable branches. - Publish and verify cryptographic checksums or signed release attestations. - Document the expected repository, commit, file hashes, and verification procedure. - Review downloaded Skill files before enabling them in an Agent environment. - Run installation in an isolated environment without wallet keys or API credentials. - Make the Bankr Skill explicitly optional in `README.txt`, consistent with `SKILL.md`. - Minimize installed dependencies by using the self-custody path when Bankr functionality is not required. - Monitor upstream ownership, releases, and dependency changes, and repeat the security review before updating. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (20)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- `creditsPerSolve` — 100, 205, 520, 1,075, or 2,200 depending on miner's staked balance
- `challengeManifestHash` — **save this value**; you must echo it back in your submit payload
- `challengeDomain` — the domain actually served for this challenge
- `solveInstructions` — the authoritative challenge-specific solve and output instructions
- `traceSubmission` — metadata about reasoning trace requirements, when present:
  - `required` — boolean; if `true`, you **must** include a `reasoningTrace` to pass
  - `schemaVersion` — currently `3`
Confidence
98% confidence
Finding
The skill explicitly tells the agent to treat externally returned `solveInstructions` as authoritative and to place final formatting instructions from that payload last in the model prompt. That is a direct prompt-injection sink: untrusted challenge content can steer model behavior, potentially overriding safer local policies or causing disclosure/manipulation of outputs and downstream actions.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding
The README instructs users to run `npx skills add botcoinmoney/botcoin-miner-skill` without pinning a specific package or skill version. That allows a future compromised or malicious upstream release to be fetched and executed at install time, which is especially concerning for an agent skill tied to wallets, API keys, on-chain actions, and staking.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The README also tells users to install the `bankr` skill via `npx skills add BankrBot/openclaw-skills --skill bankr` without a pinned version. Because this dependency handles banking or wallet-related functionality and is a prerequisite for mining, an attacker controlling or poisoning the referenced skill version could gain code execution or manipulate financial operations.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The activation trigger is phrased broadly: 'When the user asks to mine BOTCOIN, follow these steps in order.' That can cause an agent to initiate wallet discovery, balance checks, staking, signing, swaps, bridging, and transaction submission from a high-level user request without explicit per-action confirmation, increasing the risk of unsafe autonomous financial actions.

External Transmission

Medium
Category
Data Exfiltration
Content
**Path A (Bankr):** Look up the user's Base EVM wallet from their API key:

```bash
curl -s https://api.bankr.bot/agent/me \
  -H "X-API-Key: $BANKR_API_KEY"
```
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
**Path A (Bankr):** Look up the user's Base EVM wallet from their API key:

```bash
curl -s https://api.bankr.bot/agent/me \
  -H "X-API-Key: $BANKR_API_KEY"
```
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
**Path A (Bankr):** Look up the user's Base EVM wallet from their API key:

```bash
curl -s https://api.bankr.bot/agent/me \
  -H "X-API-Key: $BANKR_API_KEY"
```
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
```bash
# Check balances
curl -s -X POST https://api.bankr.bot/agent/prompt \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d '{"prompt": "what are my balances on base?"}'
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
If BOTCOIN is below 5M, swap into it (Bankr uses Uniswap pools, not Clanker):

```bash
curl -s -X POST https://api.bankr.bot/agent/prompt \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d '{"prompt": "swap $10 of ETH to 0xA601877977340862Ca67f816eb079958E5bd0BA3 on base"}'
Confidence
94% confidence
Finding
This natural-language prompt instructs an external custodial service to perform a token swap. In context, it can spend user funds based on skill logic and broad activation, and natural-language transaction intents are harder to validate than structured allowlisted actions, increasing the chance of unintended or manipulated financial operations.

External Transmission

Medium
Category
Data Exfiltration
Content
If ETH is zero or below ~0.001:

```bash
curl -s -X POST https://api.bankr.bot/agent/prompt \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d '{"prompt": "bridge $2 of ETH to base"}'
Confidence
93% confidence
Finding
This prompt asks an external service to bridge funds to Base, a state-changing financial action. In the skill context, bridging can move assets across chains and incur fees or loss if parameters are wrong, so initiating it from agent logic without explicit confirmation is dangerous.

External Transmission

Medium
Category
Data Exfiltration
Content
**Path A — Bankr:** Use **`POST /wallet/submit`** (the old `/agent/submit` route was retired and now returns 404):

```bash
curl -s -X POST https://api.bankr.bot/wallet/submit \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d '{
Confidence
96% confidence
Finding
This Bankr submission is used for staking-related contract calls with coordinator-supplied calldata. That can approve token spending and lock assets into staking based on externally supplied transaction data, so blindly forwarding it creates a high-risk path to unauthorized approvals or asset immobilization.

External Transmission

Medium
Category
Data Exfiltration
Content
MESSAGE=$(echo "$NONCE_RESPONSE" | jq -r '.message')

# Step 2A: Sign via Bankr — use /wallet/sign (the old /agent/sign route returns 404)
SIGN_RESPONSE=$(curl -s -X POST https://api.bankr.bot/wallet/sign \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d "$(jq -n --arg msg "$MESSAGE" '{signatureType: "personal_sign", message: $msg}')")
Confidence
95% confidence
Finding
This is a duplicate signing finding. External signing of upstream-provided messages is sensitive because signatures can authorize access or bind identity, and the agent is instructed to proceed programmatically.

External Transmission

Medium
Category
Data Exfiltration
Content
MESSAGE=$(echo "$NONCE_RESPONSE" | jq -r '.message')

# Step 2A: Sign via Bankr — use /wallet/sign (the old /agent/sign route returns 404)
SIGN_RESPONSE=$(curl -s -X POST https://api.bankr.bot/wallet/sign \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d "$(jq -n --arg msg "$MESSAGE" '{signatureType: "personal_sign", message: $msg}')")
Confidence
95% confidence
Finding
This is a duplicate signing finding. External signing of upstream-provided messages is sensitive because signatures can authorize access or bind identity, and the agent is instructed to proceed programmatically.

External Transmission

Medium
Category
Data Exfiltration
Content
SIGNATURE=$(cast wallet sign --private-key "$MINER_PRIVATE_KEY" "$MESSAGE")

# Step 3: Verify and obtain token (and auto-bind if available)
VERIFY_RESPONSE=$(curl -s -X POST "${COORDINATOR_URL:-https://coordinator.agentmoney.net}/v1/auth/verify" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg miner "$MINER_ADDRESS" \
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
```bash
NONCE=$(openssl rand -hex 16)   # or uuidgen, or any unique string per request
curl -s "${COORDINATOR_URL:-https://coordinator.agentmoney.net}/v1/challenge?miner=$MINER_ADDRESS&nonce=$NONCE" \
  -H "Authorization: Bearer $TOKEN"
```
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
**Path A — Bankr** (`POST /wallet/submit`; the old `/agent/submit` route is gone). First the receipt:

```bash
curl -s -X POST https://api.bankr.bot/wallet/submit \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d '{
Confidence
97% confidence
Finding
This is a duplicate of the raw transaction submission finding. Posting receipt transactions via a custodial submit API can cause irreversible on-chain effects if calldata is malicious or mistaken.

External Transmission

Medium
Category
Data Exfiltration
Content
**Path A — Bankr** (`POST /wallet/submit`; the old `/agent/submit` route is gone). First the receipt:

```bash
curl -s -X POST https://api.bankr.bot/wallet/submit \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d '{
Confidence
97% confidence
Finding
This is a duplicate of the raw transaction submission finding. Posting receipt transactions via a custodial submit API can cause irreversible on-chain effects if calldata is malicious or mistaken.

External Transmission

Medium
Category
Data Exfiltration
Content
Then the vouch transaction (same pattern, fields from `vouchTransaction`):

```bash
curl -s -X POST https://api.bankr.bot/wallet/submit \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BANKR_API_KEY" \
  -d '{
Confidence
92% confidence
Finding
The skill also submits a second on-chain vouch transaction from coordinator-provided data. Even if described as non-gating and fire-and-forget, it still authorizes an irreversible state change and should not be blindly executed.

External Transmission

Medium
Category
Data Exfiltration
Content
**Path A — Bankr** (`POST /wallet/submit`, synchronous, no job polling):

   ```bash
   curl -s -X POST https://api.bankr.bot/wallet/submit \
     -H "Content-Type: application/json" \
     -H "X-API-Key: $BANKR_API_KEY" \
     -d '{
Confidence
95% confidence
Finding
Claim transactions are state-changing on-chain actions that may move rewards and incur gas costs. Because the skill instructs the agent to fetch calldata from an external coordinator and submit it directly, a compromised dependency or logic error could lead to unauthorized or malformed claims and other contract interactions.

Unbounded Resource Access

Medium
Category
Excessive Agency
Content
- **Nonce mismatch on submit**: If you get "ChallengeId mismatch", ensure you're sending the same nonce you used when requesting the challenge.
- **Manifest mismatch (409)**: The `challengeManifestHash` does not match. Fetch a new challenge and use the fresh manifest hash.
- **Consistent failures across many challenges**: If the LLM fails repeatedly after many different challenges, stop and inform the user. Suggest adjusting model selection or thinking budget — see the configuration notes in Step B.
- **Do NOT** loop indefinitely. Each attempt costs LLM credits.

### LLM provider errors (stop immediately, do not retry)
- **401 / 403 from LLM API**: Authentication or permissions issue. Stop and tell the user to check their API key.
Confidence
75% confidence
Finding
Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Static analysis

No suspicious patterns detected.