T09 · Insecure Skill Coding Practices
- Location
miner/src/index.ts:39- Finding
AI API credentials can be transmitted over plaintext HTTP
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
miner/src/index.ts:39AI API credentials can be transmitted over plaintext HTTP
miner/src/index.ts:98Interactive secrets are echoed and existing .env permissions may remain insecure
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.
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.
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.
### Step 3: Configure the .env File
The user creates the `.env` file in the `miner/` directory. There are two methods:
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.
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`:
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.
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:
cat > .env << 'EOF'
# === Wallet ===
PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE
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.
CRITICAL: Protect the file:
chmod 600 .env
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.
| 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:
set -a && source .env && set +a
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.
Note on .env loading: If the system does not use dotenv (e.g., on a deployed server), load environment variables manually before running:
set -a && source .env && set +a
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.
| `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
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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> =>
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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> =>
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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> =>
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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> =>
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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> =>
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.
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.');
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.
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.
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.
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.
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.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
- 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.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
- 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.
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.
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
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.
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.