Back to skill

Security audit

Web3 Ops

Security checks for vulnerabilities and agentic risk

Overview

This crypto-wallet skill is purpose-built for on-chain operations, but it exposes fund-moving actions and wallet secrets to AI-connected workflows without strong enough safety boundaries.

Review before installing. Use only a dedicated low-value wallet, do not put a main wallet private key or mnemonic in an agent-accessible .env or MCP config, avoid enabling MCP transaction tools unless you add your own confirmation and spending limits, and treat create-wallet output as immediately sensitive because it prints recovery material.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (6)

T09 · Insecure Skill Coding Practices

Error
Location
actions/wallet.js:384
Finding

Generated Wallet Private Key and Mnemonic Are Exposed Through Process Output

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
mcp-server.js:239
Finding

MCP Tools Can Sign and Broadcast Asset Transfers and Arbitrary Transactions Without Mandatory Human Confirmation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
actions/swapBridge.js:17
Finding

Unlimited ERC-20 Allowances Are Granted to Spenders Selected by Remote Quote Services

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
actions/swapBridge.js:185
Finding

Direct Uniswap and PancakeSwap Routes Set Minimum Output to Zero

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
actions/common.js:399
Finding

Model-Controlled Custom RPC URLs Permit Server-Side Requests to Arbitrary Endpoints

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
bin/install.js:71
Finding

Installer Resolves Mutable Dependencies Without a Lockfile and Recommends Unversioned Remote Execution

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (84)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README asserts explicit human approval for any on-chain transaction, but later describes MCP/agent-exposed tools like transfer, swap, bridge, mint_nft, and custom_tx without documenting an enforced confirmation gate. In an LLM-connected execution environment, this mismatch can cause operators to overtrust the tool and permit autonomous fund-moving actions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README makes a security claim that the skill never stores or accesses mnemonics/seed phrases during operations, yet elsewhere documents wallet generation that writes mnemonic material to .env. This is dangerous because users may rely on a false security boundary and expose recovery secrets in plaintext local storage.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README instructs users to store a wallet private key in a .env file for an AI-integrated skill. This creates a direct path for the runtime that interprets natural language and executes wallet operations to access high-value credentials, undermining the claimed zero-knowledge separation.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

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

``

Mint NFT

Mint an NFT on Base by calling the claim(address,uint256) function with arguments:

bash
node index.js mint --chain base --contract 0x123456789... --function "claim(address,uint256)" --args '["0xYourAddress", 1]' --value 0.00075

Broadcast Custom Transaction

Send custom hex data to a smart contract:

bash
node index.js custom --chain base --to 0xTargetAddress --data 0xa9059cbb000000000000000000000000742d35cc6634c0532925a3b844bc454e4438f44e0000000000000000000000000000000000000000000000000de0b6b3a7640000

📖 Real-World User-Agent Workflows & Demos

Below are standard interaction cycles showing how an AI Agent (e.g. OpenClaw) leverages the web3-ops skill under the hood to fulfill user requests safely and present natural-language responses.

1. Simple Read: "check ETH balance"

When a user asks to inspect their balance, the agent resolves the chain name and runs a read-only query.

text
User  💬: "How much ETH do I have on Base?"

Age

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The agent integration section tells users to place the wallet private key in the agent project's main .env, making the secret available to the broader agent environment rather than a tightly isolated signing component. In context, this is especially dangerous because the same environment may host multiple tools, prompts, and logs that can leak or misuse the key.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The MCP configuration example embeds a private key directly in the LLM-connected client configuration. That gives a language-model-adjacent toolchain direct access to a spend-authorizing credential and materially raises the risk of prompt-induced misuse, local compromise, or accidental disclosure.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The skill explicitly states it loads secrets from a local .env file into the runtime for transaction signing. Even though this is presented as a security feature, any agent-integrated tool that reads private keys from environment-backed local files materially increases risk: compromise of the runtime, prompt-induced transaction execution, verbose logging, misconfigured containers, or directory exposure could lead to irreversible theft of on-chain assets.

Content

Scanner excerpt · SECURITY.md (reported line 17)May include surrounding context.

md
graph TD
    A[AI Agent / LLM Interface] -->|1. Generates CLI Command| B(web3-ops Runtime)
    subgraph Local Secure Host Sandbox
        B -->|2. Loads Secrets| C[.env File / Host Process]
        B -->|3. Signs Tx Client-Side| D[Ethers.js Signer]
        D -->|4. Private Key Purged| E((RAM Garbage Collection))
    end

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The skill explicitly loads a .env file from the parent directory, creating direct access to locally stored credentials. In combination with wallet construction later in the module, this grants the skill privileged access to private blockchain keys and other secrets without any visible trust boundary.

Content

Scanner excerpt · actions/common.js (reported line 10)May include surrounding context.

js
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Load .env from root of skill directory
dotenv.config({ path: path.join(__dirname, "../.env") });

// ANSI Terminal Colors

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The module initialization path includes secret loading from .env, meaning credential access happens as soon as the file is imported. That pattern is dangerous because benign-looking operations elsewhere in the skill may inadvertently gain access to sensitive data and signing authority.

Content

Scanner excerpt · actions/common.js (reported line 11)May include surrounding context.

js
const __dirname = path.dirname(__filename);

// Load .env from root of skill directory
dotenv.config({ path: path.join(__dirname, "../.env") });

// ANSI Terminal Colors
export const COLORS = {

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This monitor is not passive: when a price threshold is met, it immediately initiates a token swap via swapOrBridge. That couples observation with irreversible asset movement, so a transient price spike, manipulated price feed, bad configuration, or misunderstood invocation can directly trigger an unintended trade and loss of funds.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · actions/wallet.js (reported line 355)May include surrounding context.

js
// Generate new random wallet and save to .env
export async function createNewWallet(options = {}) {
  const envPath = path.join(__dirname, "../.env");
  const force = !!options.force;

  try {

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This code writes a newly generated private key and mnemonic into a plaintext .env file. Even with mode 0600, plaintext secret storage is risky in agent environments because the file may be copied into backups, committed accidentally, read by other local processes under the same user, or exposed through workspace tooling.

Content

Scanner excerpt · actions/wallet.js (reported line 406)May include surrounding context.

js
newEnvContent = setEnvVar(newEnvContent, "PRIVATE_KEY", pkLine);
    newEnvContent = setEnvVar(newEnvContent, "MNEMONIC", mnemonicLine);

    // Write to .env
    fs.writeFileSync(envPath, newEnvContent, { mode: 0o600 });

    if (!options.json) {

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The function generates a new wallet, writes the private key and mnemonic to a local .env file, and then returns and prints those secrets in structured output. In JSON mode, the warning banner is skipped but the secrets are still emitted, which makes accidental leakage through logs, agent transcripts, CI output, or downstream tool capture very likely.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · bin/install.js (reported line 70)May include surrounding context.

js
const basename = path.basename(src);
    if (
      basename === 'package-lock.json' || 
      basename === '.env' || 
      basename === '.gitattributes'
    ) {
      return;

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · bin/install.js (reported line 98)May include surrounding context.

js
const basename = path.basename(src);
    if (
      basename === 'package-lock.json' || 
      basename === '.env' || 
      basename === '.gitattributes'
    ) {
      return;

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · actions/common.js (reported line 462)May include surrounding context.

js
copyRecursiveSync(packageRoot, dest);
  console.log(`${colors.green}✔ Files copied successfully.${colors.reset}`);

  // Create .env from .env.example if not exists
  const envExamplePath = path.join(dest, '.env.example');
  const envPath = path.join(dest, '.env');
  if (fs.existsSync(envExamplePath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · actions/common.js (reported line 477)May include surrounding context.

js
copyRecursiveSync(packageRoot, dest);
  console.log(`${colors.green}✔ Files copied successfully.${colors.reset}`);

  // Create .env from .env.example if not exists
  const envExamplePath = path.join(dest, '.env.example');
  const envPath = path.join(dest, '.env');
  if (fs.existsSync(envExamplePath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · actions/wallet.js (reported line 353)May include surrounding context.

js
copyRecursiveSync(packageRoot, dest);
  console.log(`${colors.green}✔ Files copied successfully.${colors.reset}`);

  // Create .env from .env.example if not exists
  const envExamplePath = path.join(dest, '.env.example');
  const envPath = path.join(dest, '.env');
  if (fs.existsSync(envExamplePath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · bin/install.js (reported line 96)May include surrounding context.

js
copyRecursiveSync(packageRoot, dest);
  console.log(`${colors.green}✔ Files copied successfully.${colors.reset}`);

  // Create .env from .env.example if not exists
  const envExamplePath = path.join(dest, '.env.example');
  const envPath = path.join(dest, '.env');
  if (fs.existsSync(envExamplePath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · bin/install.js (reported line 102)May include surrounding context.

js
copyRecursiveSync(packageRoot, dest);
  console.log(`${colors.green}✔ Files copied successfully.${colors.reset}`);

  // Create .env from .env.example if not exists
  const envExamplePath = path.join(dest, '.env.example');
  const envPath = path.join(dest, '.env');
  if (fs.existsSync(envExamplePath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · bin/install.js (reported line 104)May include surrounding context.

js
copyRecursiveSync(packageRoot, dest);
  console.log(`${colors.green}✔ Files copied successfully.${colors.reset}`);

  // Create .env from .env.example if not exists
  const envExamplePath = path.join(dest, '.env.example');
  const envPath = path.join(dest, '.env');
  if (fs.existsSync(envExamplePath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · bin/install.js (reported line 107)May include surrounding context.

js
copyRecursiveSync(packageRoot, dest);
  console.log(`${colors.green}✔ Files copied successfully.${colors.reset}`);

  // Create .env from .env.example if not exists
  const envExamplePath = path.join(dest, '.env.example');
  const envPath = path.join(dest, '.env');
  if (fs.existsSync(envExamplePath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

This command explicitly manages wallet credentials by generating a new EVM wallet and configuring its secrets in a .env file, which is plaintext credential handling. Private keys and mnemonics stored this way are highly sensitive and may be exposed via filesystem access, shell history, backups, CI artifacts, or accidental repository commits, leading to full wallet compromise.

Content

Scanner excerpt · index.js (reported line 195)May include surrounding context.

js
// 14. Create EVM Wallet
program
  .command("create-wallet")
  .description("Generate a random EVM wallet and configure its credentials in the .env file")
  .option("--force", "Force overwrite of existing PRIVATE_KEY or MNEMONIC in .env", false)
  .action((options) => {
    createNewWallet(getMergedOpts(options));

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The --force option allows overwriting existing PRIVATE_KEY or MNEMONIC values in the .env file, amplifying the credential-handling risk by enabling destruction or replacement of active wallet secrets. In an agent environment, misuse of this option could sever access to funds or redirect future transactions to a newly generated wallet under unintended control.

Content

Scanner excerpt · index.js (reported line 196)May include surrounding context.

js
program
  .command("create-wallet")
  .description("Generate a random EVM wallet and configure its credentials in the .env file")
  .option("--force", "Force overwrite of existing PRIVATE_KEY or MNEMONIC in .env", false)
  .action((options) => {
    createNewWallet(getMergedOpts(options));
  });

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

This server exposes high-risk wallet operations such as transfer, swap, bridge, mint_nft, and custom_tx directly to an MCP client with no built-in confirmation, policy gate, address allowlist, simulation enforcement, or human approval workflow. In an agent context, that makes prompt injection, tool misuse, or model error materially more dangerous because a caller can trigger irreversible blockchain transactions and asset loss.

Content

No source excerpt is available for this finding.