Back to skill

Security audit

fetch-evm-logs

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it handles user RPC endpoints and package installation in ways that can expose credentials or reach unintended network destinations.

Install only if you are comfortable with it running a Node package install and making network calls to public ABI services plus the RPC URLs you provide. Prefer a dedicated public HTTPS RPC endpoint without embedded secrets, avoid command-line API keys, review generated package versions before install, and do not use private-chain addresses or proprietary ABIs unless you are comfortable storing them in the project directory.

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

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
templates/src/utils/utils.pull.log.ts:16
Finding

Unrestricted RPC URLs Allow Requests to Internal Network Services

Content
View full analysis
u.trim()) .filter(Boolean); if (!list.length) { throw new Error('At least one RPC URL is required'); } return list; } function createProvider(url: string) { return new ethers.JsonRpcProvider(url, undefined, { batchMaxCount: 1 }); } ``` The RPC type accepts arbitrary strings: ```typescript rpc: string | string[]; ``` ### Technical Analysis The application passes user-configured RPC URLs directly to `ethers.JsonRpcProvider`. It does not validate the URL scheme, destination hostname, resolved IP address, port, or redirect behavior. This permits the process to send JSON-RPC requests to loopback, link-local, private-network, or otherwise privileged endpoints reachable from the Agent's execution environment. Support for custom EVM chains makes configurable RPC endpoints necessary, but unrestricted access to internal destinations exceeds a safe default privilege boundary. The request methods are constrained by the application to Ethereum JSON-RPC operations such as `eth_blockNumber` and `eth_getLogs`; this is not a fully arbitrary HTTP-request primitive. Nevertheless, it can interact with internal services, disclose their reachability through error differences, and potentially communicate with internal JSON-RPC-compatible services. ### Attack Path 1. An attacker supplies an RPC URL pointing to an internal destination, such as a loopback address, RFC1918 address, link-local address, or internal DNS name. 2. The Agent places that URL in `contract.ts` as instructed by the Skill. 3. The Agent run ...[truncated 929 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
templates/src/utils/utils.pull.log.ts:47
Finding

Authenticated RPC URLs Are Written to Console Output Without Redaction

Content
View full analysis
( label: string, fn: (p: ethers.JsonRpcProvider) => Promise, ): Promise { let lastErr: unknown; for (let rotate = 0; rotate < rpcs.length; rotate++) { for (let attempt = 1; attempt <= retriesPerRpc; attempt++) { try { return await fn(provider); } catch (err) { lastErr = err; const msg = err instanceof Error ? err.message : String(err); console.warn( `${label} failed on rpc[${rpcIndex}] attempt ${attempt}/${retriesPerRpc}: ${msg}`, ); await sleep(2); } } rpcIndex = (rpcIndex + 1) % rpcs.length; provider = createProvider(rpcs[rpcIndex]); console.warn(`switching RPC → rpc[${rpcIndex}]: ${rpcs[rpcIndex]}`); } ``` ### Technical Analysis Commercial RPC providers commonly place authentication material in URL paths, query parameters, or userinfo. Examples include: ```text https://provider.example/v3/SECRET_TOKEN https://provider.example/rpc?apikey=SECRET_TOKEN ``` The implementation prints the complete configured RPC URL when starting and whenever failover occurs. Consequently, credentials embedded in the URL are copied into terminal output, Agent transcripts, CI logs, monitoring systems, and potentially support diagnostics. Error messages returned by the provider are also printed without sanitization. Depending on the underlying library and server response, those errors may repeat the complete endpoint. ### Attack Path 1. A user supplies a private RPC endpoint containing an API token. 2. The Agent places the endpoint in `contract.ts`. 3. The Age ...[truncated 737 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
init-project.sh:29
Finding

Automatic Dependency Installation Uses Mutable Versions Without a Lockfile

Content
View full analysis
/dev/null 2>&1; then (cd "$TARGET_DIR" && pnpm install) elif command -v npm >/dev/null 2>&1; then (cd "$TARGET_DIR" && npm install) else echo "No pnpm/npm found. Run install manually in $TARGET_DIR" exit 1 fi ``` From `templates/package.json`: ```json { "packageManager": "pnpm@10.8.1", "dependencies": { "decimal.js": "^10.6.0", "ethers": "^6.17.0" }, "devDependencies": { "@types/node": "^26.1.0", "tsx": "^4.23.0", "typescript": "^6.0.3" } } ``` ### Technical Analysis Project initialization automatically invokes a package manager. The template does not include a lockfile, and all dependencies use caret ranges. As a result, package resolution can select versions newer than those reviewed with the Skill. Package installation may execute dependency lifecycle scripts with the permissions of the user running the Agent. If a dependency, transitive dependency, registry account, or package-resolution process is compromised, code not present during this audit could execute during initialization. The identified package names are established ecosystem packages; the audit found no evidence that the declared packages are intentionally malicious. The risk arises from automatic installation, mutable resolution, and lack of a reviewed lockfile. ### Attack Path 1. The user or Agent invokes `init-project.sh`. 2. The script copies the template and immediately runs `pnpm install` or `npm install`. 3. The package manager resolves caret ranges using the current registry state. 4. A newly publishe ...[truncated 834 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
templates/src/paths.ts:6
Finding

Unvalidated Contract Addresses Are Incorporated into Filesystem Paths

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/fetch-abi.mjs:5
Finding

Etherscan API Key Can Be Exposed Through Command-Line Arguments

Content
View full analysis
= 0 && process.argv[i + 1]) return process.argv[i + 1]; return fallback; } const chainId = Number(arg('chainId')); const address = String(arg('address', '')).toLowerCase(); const outDir = path.resolve(arg('out', path.join(process.cwd(), 'src/abi'))); const etherscanKey = arg('etherscanKey') || process.env.ETHERSCAN_API_KEY || ''; ``` The key is then placed in the Etherscan query string: ```javascript async function fromEtherscan() { if (!etherscanKey) return null; const url = `https://api.etherscan.io/v2/api?chainid=${chainId}` + `&module=contract&action=getabi&address=${address}&apikey=${etherscanKey}`; const res = await fetch(url); ``` ### Technical Analysis Sending the key over HTTPS to the official Etherscan API is necessary for the documented authenticated fallback and is not unrelated exfiltration. However, accepting the key through `--etherscanKey KEY` places the secret in the process argument vector. Command-line arguments may be visible through process-inspection tools, shell history, terminal transcripts, CI command logs, or Agent conversation records. Placing the key in the URL query string may also expose it if request URLs are captured by local debugging tools or proxy diagnostics, although the current script does not explicitly log the URL. The environment-variable alternative is already suppo ...[truncated 931 chars]
Remediation
View remediation
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A description-behavior mismatch is security-relevant because users and orchestrators may approve the skill expecting only EVM log retrieval, while the actual implementation appears to include broader local file processing and lacks evidence of the promised RPC/ABI functionality. That mismatch can hide unexpected data handling and defeats informed consent, making abuse or accidental exposure harder to detect.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 211)May include surrounding context.

md
- [scripts/list-events.mjs](scripts/list-events.mjs)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill instructs use of shell scripts, Node programs, public ABI lookup services, local file reads, and environment-based API keys, but it does not declare any explicit tool scope or permissions boundary. That creates an authorization gap where a host agent may grant broader file, network, or env access than the user expects, increasing the chance of unintended data access or exfiltration.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description says to trigger when the user asks to "get, pull, fetch, sync, or download contract event logs," and later says to still start the skill for a vague ask like getting smart-contract logs. Terms like "get" and "fetch" are broad, and the examples explicitly allow underspecified requests, which increases the chance of unintended invocation overlap with other blockchain or analytics skills.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill sends contract identifiers to public services like Sourcify or Etherscan-compatible APIs without warning the user that contract metadata, chain selection, and lookup timing may be disclosed to third parties. In sensitive environments, even a contract address or private-chain identifier can be confidential, so silent external lookup creates avoidable privacy and operational risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The skill instructs persistent storage of user-supplied ABI data to a local project path, which can retain sensitive contract metadata beyond the immediate session. If the ABI is proprietary, private, or user-provided from confidential sources, writing it to disk without a retention warning or cleanup guidance increases the risk of unintended disclosure to later processes or users on the same system.

Content

Scanner excerpt · SKILL.md (reported line 102)May include surrounding context.

  • Paste JSON in chat
  • Point to a local file

Then write it to:

text
src/abi/abi_{address}_{chainId}.json

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fetch-abi.mjs (reported line 55)May include surrounding context.

js
async function fromEtherscan() {
  if (!etherscanKey) return null;
  const url =
    `https://api.etherscan.io/v2/api?chainid=${chainId}` +
    `&module=contract&action=getabi&address=${address}&apikey=${etherscanKey}`;
  const res = await fetch(url);
  if (!res.ok) return null;

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · SKILL.md (reported line 16)May include surrounding context.

md
# Fetch EVM Logs

Pull event logs from **any EVM contract** on any EVM-compatible chain (Ethereum mainnet/testnets, L2s, sidechains, custom chains) — not limited to a specific protocol or event type. You only need `chainId`, `contractAddress`, an RPC, and an ABI (auto-fetched or user-provided).

Self-contained skill: **scaffold → chainId + address → get ABI → pick events → pull + parse**.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · templates/package.json (reported line 13)May include surrounding context.

json
"license": "ISC",
  "packageManager": "pnpm@10.8.1",
  "dependencies": {
    "decimal.js": "^10.6.0",
    "ethers": "^6.17.0"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · templates/package.json (reported line 14)May include surrounding context.

json
"packageManager": "pnpm@10.8.1",
  "dependencies": {
    "decimal.js": "^10.6.0",
    "ethers": "^6.17.0"
  },
  "devDependencies": {
    "@types/node": "^26.1.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · templates/package.json (reported line 17)May include surrounding context.

json
"ethers": "^6.17.0"
  },
  "devDependencies": {
    "@types/node": "^26.1.0",
    "tsx": "^4.23.0",
    "typescript": "^6.0.3"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · templates/package.json (reported line 18)May include surrounding context.

json
},
  "devDependencies": {
    "@types/node": "^26.1.0",
    "tsx": "^4.23.0",
    "typescript": "^6.0.3"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · templates/package.json (reported line 19)May include surrounding context.

json
"devDependencies": {
    "@types/node": "^26.1.0",
    "tsx": "^4.23.0",
    "typescript": "^6.0.3"
  }
}

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/fetch-abi.mjs:20