Back to skill

Security audit

$CLAW Mining - Proof of AI Work

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real CLAW mining workflow, but it asks users to store and sometimes type a live Ethereum private key while enabling automated mainnet transactions.

Install only if you are comfortable running a wallet-connected miner locally. Use a dedicated hot wallet with minimal ETH, never a main wallet or hardware-wallet seed, review the cloned code before npm install/npx, avoid custom AI endpoints unless they are HTTPS and trusted, and do not leave the auto miner running unless you intend it to keep signing mining transactions.

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

T09 · Insecure Skill Coding Practices

Error
Location
miner/src/index.ts:39
Finding
AI API credentials can be transmitted over plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `miner/src/index.ts:39-51`, `miner/src/config.ts:50-51`, `miner/src/ai-api.ts:17-22` **Vulnerability Type**: Missing transport-security validation for a credential-bearing endpoint **Risk Level**: High ### Vulnerable Code ```ts // miner/src/index.ts:39-51 if (providerChoice === '2') { aiApiUrl = 'https://openrouter.ai/api/v1/chat/completions'; aiModel = 'x-ai/grok-4.1-fast'; aiApiKey = await ask('? Enter your OpenRouter API key: '); console.log(`\n ✓ Using OpenRouter → model: ${aiModel}`); } else if (providerChoice === '3') { aiApiUrl = await ask('? Enter custom AI API URL: '); aiModel = (await ask('? Enter AI model name (default: grok-4.1-fast): ')) || 'grok-4.1-fast'; aiApiKey = await ask('? Enter your API key: '); } else { aiApiUrl = 'https://api.x.ai/v1/chat/completions'; aiModel = 'grok-4.1-fast'; aiApiKey = await ask('? Enter your xAI API key: '); } ``` ```ts // miner/src/config.ts:50-51 aiApiKey: requireEnv('AI_API_KEY'), aiApiUrl: envOrDefault('AI_API_URL', 'https://api.x.ai/v1/chat/completions'), ``` ```ts // miner/src/ai-api.ts:17-22 const res = await fetch(config.apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.apiKey}`, }, ``` ### Technical Analysis The miner supports a user-controlled custom `AI_API_URL` and sends `AI_API_KEY` to that URL in an HTTP `Authorization` header. No validation requires the endpoint to use HTTPS. The project performs an HTTPS check for `ORACLE_URL`, but no equivalent validation is applied to `AI_API_URL`. Consequently, a value such as `http://example.test/v1/chat/completions` is accepted. HTTP does not provide transport confidentiality or server authentication, so any party capable of observing or modifying the connection can recover the Bearer token and alter the API response. This issue does not expose the Ethereum private key because the private key is not included in ...[truncated 1403 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse `AI_API_URL` with the standard `URL` class rather than using string-prefix checks. 2. Require the `https:` protocol for every non-loopback endpoint. 3. If local development requires HTTP, permit only explicitly recognized loopback hosts such as `localhost`, `127.0.0.1`, and `[::1]`. 4. Reject malformed URLs, embedded username/password components, and unsupported protocols. 5. Apply the validation both during interactive initialization and when loading environment variables so manually edited configurations cannot bypass it. 6. Consider requiring explicit confirmation before sending credentials to a custom hostname. Example validation: ```ts function validateCredentialEndpoint(rawUrl: string): string { let parsed: URL; try { parsed = new URL(rawUrl); } catch { throw new Error('AI_API_URL must be a valid absolute URL'); } const loopbackHosts = new Set(['localhost', '127.0.0.1', '[::1]']); const isLoopback = loopbackHosts.has(parsed.hostname); if (parsed.protocol !== 'https:' && !(isLoopback && parsed.protocol === 'http:')) { throw new Error( 'AI_API_URL must use HTTPS; HTTP is permitted only for loopback development endpoints' ); } if (parsed.username || parsed.password) { throw new Error('AI_API_URL must not contain embedded credentials'); } return parsed.toString(); } ``` Use the validated value in `loadConfig()` before constructing `MinerConfig`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
miner/src/index.ts:98
Finding
Interactive secrets are echoed and existing .env permissions may remain insecure<![CDATA[ ## Vulnerability Details **File Location**: `miner/src/index.ts:41-57`, `miner/src/index.ts:98-104`, `miner/src/index.ts:137` **Vulnerability Type**: Insecure secret input and file-permission handling **Risk Level**: Medium ### Vulnerable Code ```ts // miner/src/index.ts:41-57 aiApiKey = await ask('? Enter your OpenRouter API key: '); console.log(`\n ✓ Using OpenRouter → model: ${aiModel}`); } else if (providerChoice === '3') { // Custom aiApiUrl = await ask('? Enter custom AI API URL: '); aiModel = (await ask('? Enter AI model name (default: grok-4.1-fast): ')) || 'grok-4.1-fast'; aiApiKey = await ask('? Enter your API key: '); } else { // xAI Direct (default) aiApiUrl = 'https://api.x.ai/v1/chat/completions'; aiModel = 'grok-4.1-fast'; aiApiKey = await ask('? Enter your xAI API key: '); } ``` ```ts // miner/src/index.ts:98-104 const wantsKey = (await ask('? Enter private key now? [y/N] (you can add it to .env later): ')).toLowerCase(); let privateKeyValue = ''; if (wantsKey === 'y' || wantsKey === 'yes') { privateKeyValue = await ask('? Paste your private key (0x...): '); } rl.close(); ``` ```ts // miner/src/index.ts:137 fs.writeFileSync('.env', envContent, { mode: 0o600 }); ``` ### Technical Analysis The setup command obtains API keys and, optionally, the Ethereum private key using `readline.question`. This input method echoes entered characters to the terminal. Secrets can therefore be observed by nearby users and recorded in terminal captures, session recordings, remote-support logs, or other terminal-monitoring facilities. The command writes the resulting secrets to `.env` with a requested mode of `0600`. The `mode` option establishes permissions when Node.js creates a new file, but it does not reliably replace the permissions of an already-existing file opened for overwrite. If `.env` already exists with group-readable or world-readable permissions, rewriting it can retain those permissions. The setup command also ov ...[truncated 1974 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use a no-echo secret prompt for API keys and private keys. Disable terminal echo while the value is entered and restore terminal state in a `finally` block. 2. Prefer directing users to set the private key outside the interactive process if secure hidden input cannot be implemented reliably. 3. Check whether `.env` already exists and require explicit confirmation before replacing it. 4. Create a temporary file with exclusive creation flags and mode `0600`, write the complete configuration, flush and close it, and atomically rename it to `.env`. 5. Explicitly call `fs.chmodSync('.env', 0o600)` after writing. Do not rely only on the `mode` option. 6. Reject symbolic-link targets or use file operations that do not follow links where supported, preventing credentials from being redirected into an attacker-selected file. 7. Validate that the resulting path is a regular file owned by the current user. 8. Clear in-memory string references as soon as practical, while recognizing that JavaScript strings cannot be securely zeroized. A minimum permission repair should include: ```ts fs.writeFileSync('.env', envContent, { mode: 0o600, flag: 'w', }); fs.chmodSync('.env', 0o600); ``` For stronger protection, use a securely created temporary file and atomic rename instead of directly overwriting `.env`. ]]>
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (59)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The 'tell your agent mine CLAW, no technical knowledge required' framing conflicts with the actual workflow, which requires cloning code, managing `.env` secrets, handling RPC/API credentials, and potentially entering a private key via CLI. That mismatch can cause users to underestimate the risk of credential exposure and transaction signing.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The 'tell your agent mine CLAW, no technical knowledge required' framing conflicts with the actual workflow, which requires cloning code, managing `.env` secrets, handling RPC/API credentials, and potentially entering a private key via CLI. That mismatch can cause users to underestimate the risk of credential exposure and transaction signing.

Credential Access

High
Category
Privilege Escalation
Content
# Expected output: 1.0.0
```

### Step 3: Configure the .env File

The user creates the `.env` file in the `miner/` directory. There are two methods:
Confidence
84% confidence
Finding
The skill instructs users to create and manage a `.env` file containing a blockchain private key for live signing. Storing raw private keys in plaintext on disk materially increases the risk of credential theft from local compromise, backups, shell mistakes, or accidental disclosure.

Credential Access

High
Category
Privilege Escalation
Content
If the user skipped the private key step, tell them to open `.env` and paste their `PRIVATE_KEY` on the designated line.

#### Method B: Manual .env File

Instruct the user to create the file manually. Show them the template below but tell them to fill in their own values directly — the agent must not handle `PRIVATE_KEY`:
Confidence
84% confidence
Finding
Telling users to paste `PRIVATE_KEY` into `.env` normalizes unsafe secret handling for an Ethereum signing key. In a wallet-draining threat model, plaintext key storage is especially dangerous because compromise leads directly to asset theft, not just account access.

Credential Access

High
Category
Privilege Escalation
Content
Instruct the user to create the file manually. Show them the template below but tell them to fill in their own values directly — the agent must not handle `PRIVATE_KEY`:

```bash
cat > .env << 'EOF'
# === Wallet ===
PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE
Confidence
90% confidence
Finding
The template explicitly includes `PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE`, which encourages insecure local storage of the most sensitive credential in the system. Because the skill is designed to sign on-chain transactions, theft of this value enables immediate unauthorized transfers and irreversible financial loss.

Credential Access

High
Category
Privilege Escalation
Content
**CRITICAL**: Protect the file:

```bash
chmod 600 .env
```

#### Environment Variable Reference
Confidence
80% confidence
Finding
Although `chmod 600` is protective, the surrounding guidance still assumes plaintext secret storage in `.env`. File permission hardening does not sufficiently mitigate the core risk that a hot-wallet private key is being stored unencrypted on disk.

Credential Access

High
Category
Privilege Escalation
Content
| xAI Direct | `https://api.x.ai/v1/chat/completions` | `grok-4-1-fast-non-reasoning` | Recommended, lowest cost |
| OpenRouter | `https://openrouter.ai/api/v1/chat/completions` | `x-ai/grok-4.1-fast` | Alternative, has markup |

**Note on .env loading**: If the system does not use `dotenv` (e.g., on a deployed server), load environment variables manually before running:

```bash
set -a && source .env && set +a
Confidence
86% confidence
Finding
The recommended `set -a && source .env && set +a` workflow exposes secrets to the shell environment, where they may leak via process inspection, shell history mistakes, debugging output, or child processes. For a raw blockchain private key, this broadens exposure beyond the miner itself.

Credential Access

High
Category
Privilege Escalation
Content
**Note on .env loading**: If the system does not use `dotenv` (e.g., on a deployed server), load environment variables manually before running:

```bash
set -a && source .env && set +a
```

### Step 4: Verify Configuration
Confidence
86% confidence
Finding
This repeated advice to source `.env` into the shell reinforces a risky credential-handling pattern. In the context of a transaction-signing miner, widened environment exposure increases the chance that the private key is captured by unrelated tools or processes.

Credential Access

High
Category
Privilege Escalation
Content
| `AI API error: 401` | Invalid API key | Check `AI_API_KEY` in `.env` |
| `AI API error: 429` | API rate limit | Wait and retry, or check API quota |
| `InvalidSignature` | Oracle signing mismatch | Retry; if persistent, check Oracle status |
| `Missing required environment variable` | `.env` not loaded | Run `set -a && source .env && set +a` first, or check `.env` file exists |
| `EpochExhausted` | Epoch cap fully mined | Wait for next Epoch |

### Checking Oracle Health
Confidence
79% confidence
Finding
Troubleshooting guidance that tells users to source `.env` continues to propagate unsafe handling of sensitive credentials during routine operations. Operational repetition makes accidental disclosure more likely over time, especially for non-expert users targeted by the skill's simplified marketing.

Credential Access

High
Category
Privilege Escalation
Content
program
  .command('init')
  .description('Interactive setup — creates a .env file')
  .action(async () => {
    const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
    const ask = (q: string): Promise<string> =>
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
program
  .command('init')
  .description('Interactive setup — creates a .env file')
  .action(async () => {
    const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
    const ask = (q: string): Promise<string> =>
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
program
  .command('init')
  .description('Interactive setup — creates a .env file')
  .action(async () => {
    const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
    const ask = (q: string): Promise<string> =>
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
program
  .command('init')
  .description('Interactive setup — creates a .env file')
  .action(async () => {
    const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
    const ask = (q: string): Promise<string> =>
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
program
  .command('init')
  .description('Interactive setup — creates a .env file')
  .action(async () => {
    const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
    const ask = (q: string): Promise<string> =>
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
TASK_PROMPT=${taskPrompt}
`;

    fs.writeFileSync('.env', envContent, { mode: 0o600 });
    console.log('\n  ✓ .env file created (permissions: 600).');
    if (!privateKeyValue) {
      console.log('  ⚠  Open .env and paste your PRIVATE_KEY before running mine or auto.');
Confidence
90% confidence
Finding
The code writes highly sensitive secrets, including PRIVATE_KEY and AI_API_KEY, into a plaintext '.env' file on disk. Although mode 0600 helps, plaintext secret storage materially increases the risk of credential compromise from local malware, backups, shell history leakage via later tooling, or accidental exposure by the user in a skill ecosystem that encourages automation.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The activation phrase "mine CLAW" is broad and action-oriented for a skill that handles wallet, API, and on-chain transaction workflow automatically. In an agent environment, ambiguous triggers can cause the skill to activate from ordinary conversation or indirect mentions, increasing the chance of unintended credential prompts, transaction preparation, or mining actions involving real funds.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The phrase "Help me set up CLAW mining" is also broad for a skill that requests sensitive inputs like private keys, RPC endpoints, and API credentials as part of an automated flow. Without tighter intent gating, an agent may interpret exploratory or conversational requests as authorization to begin setup steps that expose secrets or lead to financially relevant actions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill declares no explicit tool scope even though it clearly requires environment-variable access and network connectivity. In agent platforms, missing scope declarations can cause overbroad or implicit permissions, making sensitive actions less visible to users and harder for hosts to sandbox safely.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrase 'mine CLAW' is short and generic enough that it may fire on ordinary discussion rather than deliberate consent for a wallet-linked action. In a transaction-capable skill, broad activation language increases the risk of accidental execution of setup, network access, or mining workflows.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The private-key guidance is internally inconsistent: it says the agent must not request the key in conversation, but also describes a CLI flow that may collect the private key interactively. This ambiguity increases the chance that an agent implementation or user follows the less safe path and exposes a signing key to software they do not fully trust.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- The `init` command optionally asks the user if they want to enter their private key. If they decline, the `.env` file is created with an empty `PRIVATE_KEY=` placeholder for them to fill in later. Either way, the choice is entirely the user's.
- The agent MUST NOT ask the user to paste, share, or reveal their private key in conversation. Only the CLI's local `init` prompt handles this.
- The `.env` file is created with `chmod 600` permissions (owner-only read/write).
- At runtime, the miner reads `PRIVATE_KEY` from the environment, loads it into an in-memory `ethers.Wallet` object, and removes it from the config object immediately. The key is used only for local transaction signing and is never logged, transmitted, or sent to the Oracle, AI API, or any external service.
- All transactions are signed locally by the miner process on the user's own computer.
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- The `init` command optionally asks the user if they want to enter their private key. If they decline, the `.env` file is created with an empty `PRIVATE_KEY=` placeholder for them to fill in later. Either way, the choice is entirely the user's.
- The agent MUST NOT ask the user to paste, share, or reveal their private key in conversation. Only the CLI's local `init` prompt handles this.
- The `.env` file is created with `chmod 600` permissions (owner-only read/write).
- At runtime, the miner reads `PRIVATE_KEY` from the environment, loads it into an in-memory `ethers.Wallet` object, and removes it from the config object immediately. The key is used only for local transaction signing and is never logged, transmitted, or sent to the Oracle, AI API, or any external service.
- All transactions are signed locally by the miner process on the user's own computer.
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
1. **AI API Key** — from [console.x.ai](https://console.x.ai) (format: `xai-...`) or [openrouter.ai](https://openrouter.ai)
2. **Ethereum RPC URL** — from [alchemy.com](https://www.alchemy.com) or [infura.io](https://infura.io) (format: `https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY`)

**IMPORTANT about private key**: Do NOT ask the user for their private key. Instead, instruct them to set the `PRIVATE_KEY` environment variable themselves by editing the `.env` file directly. The agent never sees, handles, or stores the private key. Use a hot wallet with some ETH for gas — NOT their main wallet or Ledger.

### Step 2: Clone and Install
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
Using `npx tsx` without a pinned version allows retrieval of whatever package version resolves at runtime. This creates a supply-chain risk where a compromised or unexpected package version could execute arbitrary code during setup or operation.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The documented `npx tsx` invocation is unpinned, so users may execute a different package version than intended. In a wallet-adjacent workflow, that increases the chance of arbitrary code execution through package compromise or dependency drift.

Static analysis

No suspicious patterns detected.