Back to skill

Security audit

Ethermail

Security checks for vulnerabilities and agentic risk

Overview

This skill is aimed at EtherMail access, but it asks users to route wallet authentication through raw private-key signing and loosely scoped browser automation.

Review this carefully before installing. Use a dedicated low-value wallet only, avoid giving raw private keys to third-party scripts, verify any WalletConnect request before signing, and prefer a pinned, reviewed connector or hardware/isolated signer. Do not use the extraction script with arbitrary URLs.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/extract-wc-uri.js:82
Finding
Unrestricted Browser Target Enables Blind Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/extract-wc-uri.js`, lines 16 and 33-43; user-controlled input originates at lines 82-89 **Vulnerability Type**: Unrestricted URL navigation / blind server-side request forgery **Risk Level**: Medium ### Vulnerable Code ```javascript async function extractWalletConnectURI(url, timeout) { // Note: Running without --no-sandbox for better security isolation // If you encounter permission issues on Linux, consider running with proper user permissions // rather than disabling sandbox const browser = await puppeteer.launch({ headless: 'new', // Security: Sandbox enabled by default (removed --no-sandbox) }); try { const page = await browser.newPage(); // Navigate to login page console.error('📧 Navigating to EtherMail...'); await page.goto(url, { waitUntil: 'networkidle2', timeout }); // Wait for page to stabilize await page.waitForTimeout(2000); // Click the wallet login button console.error('🔑 Looking for wallet login button...'); const walletButton = await page.$('[data-testid="wallet-login"], button:has-text("wallet"), [class*="wallet"]'); if (walletButton) { await walletButton.click(); await page.waitForTimeout(3000); } ``` The navigation target is populated directly from command-line input: ```javascript const args = process.argv.slice(2); let url = DEFAULT_URL; let timeout = DEFAULT_TIMEOUT; for (let i = 0; i < args.length; i++) { if (args[i] === '--url' && args[i + 1]) { url = args[++i]; } else if (args[i] === '--timeout' && args[i + 1]) { timeout = parseInt(args[++i], 10); } ``` ### Technical Analysis The `--url` argument is passed directly to `page.goto()` without validating its protocol, hostname, resolved IP address, or redirect destination. Although the Skill is specifically intended to access the EtherMail login page, the implementation permits Chromium to navigate to arbitrary at ...[truncated 2124 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `--url` option if only the EtherMail login page is required. 2. If configurability is necessary, parse the input with `new URL()` and allow only: - The `https:` protocol. - An explicit allowlist of trusted EtherMail hostnames. - Expected login paths. 3. Validate every redirect destination rather than validating only the initial URL. 4. Resolve destination hostnames and reject loopback, link-local, private, multicast, and reserved IP ranges for both IPv4 and IPv6. 5. Enable Puppeteer request interception and abort requests to disallowed origins or resolved addresses. 6. Replace broad wallet-related element matching with a precise, verified EtherMail login selector. 7. Run the browser in a network-isolated environment that cannot reach internal control-plane or metadata services. 8. Add automated tests covering direct internal URLs, alternative schemes, DNS rebinding, IPv6 loopback addresses, and public-to-private redirects. ]]>

T08 · Insecure Dependencies

Error
Location
SKILL.md:78
Finding
Unpinned External WalletConnect Skill Receives a Raw Wallet Private Key and Automatically Signs Requests<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 78-88 **Vulnerability Type**: Unpinned security-sensitive dependency with private-key exposure and automatic signing **Risk Level**: High ### Vulnerable Code ```bash # Install walletconnect-agent skill first clawdhub install walletconnect-agent # Then use its wc-connect.js script cd ~/clawd/skills/walletconnect-agent export PRIVATE_KEY="0x..." node scripts/wc-connect.js "<WC_URI>" ``` The documented behavior then states: ```text The connector will automatically sign the `personal_sign` request, completing login. ``` ### Technical Analysis The documented workflow installs `walletconnect-agent` by its mutable package name without specifying a reviewed version, immutable artifact digest, or integrity hash. It then exports a raw Ethereum private key and executes code supplied by that external Skill. This creates a high-impact supply-chain trust boundary. Any compromised, replaced, or unexpectedly changed version of the external Skill would execute while the private key is available in the process environment. Such code could read and transmit the key, sign arbitrary messages, or otherwise impersonate the wallet owner. The automatic handling of `personal_sign` also removes a critical confirmation boundary. The workflow does not require the operator to verify the WalletConnect peer, requesting origin, account, chain context, or full message before signing. A malicious or substituted WalletConnect URI could therefore solicit an attacker-controlled signature. Environment variables are preferable to embedding a secret directly in source code, but they do not safely isolate a secret from the process receiving them. All code loaded by `wc-connect.js`, including its dependencies, can access `process.env.PRIVATE_KEY`. ### Attack Path #### Supply-chain compromise path 1. The user follows the documentation and runs: ```bash clawdhub install walletconnect-agent ``` 2. The package name ...[truncated 1765 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the external Skill to a specifically reviewed, immutable version. 2. Verify its artifact with a cryptographic digest or signed provenance record before execution. 3. Review the external Skill and its complete transitive dependency tree before granting access to wallet operations. 4. Do not provide a raw private key to third-party scripts through environment variables, command-line arguments, or plaintext files. 5. Use a hardware wallet, operating-system key store, remote isolated signer, or narrowly scoped signing service that never exposes private-key material. 6. Use a dedicated low-value wallet for Agent operations and avoid wallets holding valuable assets or broad permissions. 7. Require interactive approval for every signature. 8. Before approval, display and verify: - The WalletConnect peer and origin. - The requested account. - The full unmodified message. - The request method. - The intended authentication domain and nonce. 9. Reject unexpected methods and permit only a narrowly defined login-signature format. 10. Validate WalletConnect URIs as fresh values extracted from the expected EtherMail origin and prevent arbitrary URI substitution. 11. Rotate the wallet immediately if the private key has already been supplied to an unreviewed or potentially compromised connector. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill claims to provide EtherMail access, but its concrete guidance is primarily about extracting a WalletConnect URI from the page’s Shadow DOM and using an external signing workflow to complete login. That mismatch is security-relevant because it normalizes credential-adjacent auth interception behavior and can cause users or agents to run sensitive wallet-connection steps they would not expect from an email-access skill. In this context, harvesting or relaying a WalletConnect URI can enable unauthorized session initiation or phishing-style wallet approval flows if the URI or downstream connector is mishandled.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"extract-uri": "node scripts/extract-wc-uri.js"
  },
  "dependencies": {
    "puppeteer": "^21.0.0"
  },
  "keywords": ["ethermail", "web3", "email", "walletconnect", "ai-agent"],
  "license": "MIT"
Confidence
95% confidence
Finding
The dependency is specified with a caret range (^21.0.0), which allows npm to install newer minor and patch releases without explicit review. In a security-sensitive skill that automates browser actions for Web3 and WalletConnect flows, unpinned dependencies increase supply-chain risk and make builds non-reproducible, so behavior and exposure can change over time.

Unverifiable Dependency: puppeteer has 1 known advisory(ies) (CVE-2019-5786 (Use-After-Free in puppeteer)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
83% confidence
Finding
The manifest references puppeteer without an exact pinned version, so it is not possible to verify from this file alone whether the installed release includes a version affected by known advisories. Because this skill uses browser automation in a Web3/email context, uncertainty around the exact browser automation package version increases supply-chain and patch-management risk.

Static analysis

No suspicious patterns detected.