Back to skill

Security audit

Erc8004 Register

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it handles wallet signing keys and can make live on-chain changes while also dereferencing untrusted URLs from agent metadata.

Review before installing. Use a dedicated low-value wallet, avoid putting a primary mnemonic or private key in shell history or shared environments, run --dry-run before fix, and be aware that validating or viewing agents can make outbound requests to URLs stored in on-chain metadata. Prefer an isolated Python environment with pinned dependencies.

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

Error
Location
scripts/register.py:184
Finding

Unrestricted Remote Metadata and Image Fetching Enables SSRF

Content
View full analysis

Vulnerability Details

File Location: scripts/register.py:184-200, scripts/register.py:587-608
Vulnerability Type: Server-Side Request Forgery through attacker-controlled metadata URLs
Risk Level: High

Vulnerable Code

python
def decode_data_uri(uri: str) -> Optional[Dict[str, Any]]:
    """Decode base64 data URI to JSON."""
    if uri.startswith("data:application/json;base64,"):
        b64 = uri.replace("data:application/json;base64,", "")
        try:
            json_str = base64.b64decode(b64).decode()
            return json.loads(json_str)
        except Exception as e:
            print(f"Warning: Could not decode data URI: {e}")
            return None
    elif uri.startswith("http://") or uri.startswith("https://"):
        # Fetch from URL
        try:
            req = urllib.request.Request(uri, headers={"User-Agent": "ERC8004-CLI/1.0"})
            with urllib.request.urlopen(req, timeout=10) as resp:
                return json.loads(resp.read().decode())
        except Exception as e:
            print(f"Warning: Could not fetch URI: {e}")
            return None

The image-validation path also performs an unrestricted request:

python
image = data.get("image", "")
if image:
    # Check for local paths
    if image.startswith("/") or image.startswith("./") or image.startswith("../"):
        issues.append(f"Image is a local path (not accessible): {image}")
    elif image.startswith("file://"):
        issues.append(f"Image is a file:// URL (not accessible): {image}")
    elif image.startswith("http://") or image.startswith("https://"):
        # Try to reach the image
        try:
            req = urllib.request.Request(image, method="HEAD",
                                         headers={"User-Agent": "ERC8004-Validator/1.0"})
            with urllib.request.urlopen(req, timeout=5) as resp:
                if resp.status >= 400:

...[truncated 3944 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer embedded data:application/json;base64 metadata and reject remote metadata by default.
  2. Require an explicit user option before fetching remote metadata.
  3. Permit only HTTPS and, where practical, use an explicit allowlist of trusted metadata hosts.
  4. Resolve destination hostnames before connecting and reject all loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 addresses.
  5. Protect against DNS rebinding by ensuring the validated address is the address actually used for the connection.
  6. Disable redirects or validate the hostname, resolved address, scheme, and port of every redirect destination.
  7. Explicitly deny common cloud metadata destinations, including 169.254.169.254, while retaining general IP-range validation.
  8. Restrict destination ports to approved values, normally TCP 443.
  9. Enforce response-size limits and require an appropriate JSON content type before parsing metadata.
  10. Do not automatically republish remotely fetched content. Display the exact proposed metadata and require explicit confirmation before an on-chain update.
  11. Apply the same URL policy to image validation. Consider disabling active image reachability checks and performing only syntactic validation.
  12. Align implementation with the documentation by rejecting http:// image URLs rather than accepting both HTTP and HTTPS.

T08 · Insecure Dependencies

Warning
Location
README.md:7
Finding

Security-Sensitive Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis

Vulnerability Details

File Location: README.md:7-9, SKILL.md:153-157, scripts/register.py:110-116
Vulnerability Type: Unpinned third-party dependency installation
Risk Level: Medium

Vulnerable Code and Documentation

README.md instructs users to install mutable latest package versions:

bash
# Install dependencies
pip install web3 eth-account

SKILL.md repeats the same installation command:

bash
pip install web3 eth-account

The runtime dependency check also recommends the unpinned command:

python
def check_dependencies():
    """Check for required dependencies."""
    try:
        from web3 import Web3
        from eth_account import Account
        return True
    except ImportError:
        print("Error: Missing dependencies. Install with:")
        print("  pip install web3 eth-account")
        return False

Technical Analysis

Neither dependency is pinned to a reviewed version, and no lock file or package hashes are supplied. Pip is therefore free to install whichever versions and transitive dependencies are current on the user's configured package index at installation time.

This project uses eth-account to import wallet mnemonics and private keys and to sign blockchain transactions. It uses web3 to construct and submit transactions. Code from these packages and their transitive dependencies executes in the same process as the wallet-handling code and inherits the process's filesystem, environment, and network privileges.

The audit did not find evidence that the named packages are currently malicious. The vulnerability is the absence of reproducible, integrity-verified dependency resolution in a security-sensitive wallet application. An upstream compromise, compromised package index, malicious dependency substitution, or unexpected incompatible release could affect different users after the Skill itself has already been reviewed.

...[truncated 1405 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a reviewed dependency lock file containing exact versions for direct and transitive dependencies.

  2. Include cryptographic hashes and install with:

    bash
    pip install --require-hashes -r requirements.txt
    
  3. Generate the lock file using a reproducible dependency-management tool and commit it to the project.

  4. Document the trusted Python package index and avoid untrusted mirrors or additional package sources.

  5. Update README.md, SKILL.md, and the runtime error message so all installation instructions use the locked dependency file.

  6. Run dependency vulnerability and provenance checks as part of release review.

  7. Test and review dependency upgrades before changing pinned versions.

  8. Run wallet operations in a dedicated, minimally privileged environment with restricted filesystem and network access.

  9. Prefer an isolated virtual environment rather than installing dependencies into a shared or privileged Python environment.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README explicitly instructs users to place a mnemonic phrase or raw private key into shell environment variables, but provides no warning about the extreme sensitivity of those credentials or the risk of exposure through shell history, process inspection, logs, screenshots, shared terminals, or CI environments. In a blockchain registration tool, compromise of these secrets can lead directly to wallet takeover and irreversible loss of funds or unauthorized on-chain actions, making the documentation materially unsafe.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents capabilities that require network access and use of sensitive environment variables, but it does not declare any explicit tool scope such as permissions or allowed-tools. In an agent setting, this weakens least-privilege boundaries and can allow the skill to be invoked with broader access than users or orchestrators expect, increasing the chance of unauthorized network calls or secret exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The fix command is described as automatically repairing registration issues, but the documentation does not prominently warn that this can make live on-chain metadata changes. In this context, users may run it as a routine health action without realizing it can mutate public registry state, potentially causing unintended or irreversible updates and transaction costs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation instructs users to place a mnemonic or private key into environment variables but provides no prominent warning about the sensitivity of those credentials or the risk of fund/identity compromise. Because this skill performs on-chain registration and updates, exposure of these secrets could let an attacker take over the wallet and submit arbitrary transactions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

decode_data_uri fetches arbitrary http/https metadata and later validation performs HEAD requests to arbitrary image URLs, meaning untrusted on-chain or user-supplied URIs can trigger outbound network requests. This enables SSRF-style behavior, privacy leaks, and reliance on attacker-controlled remote content during info/update/validate flows, especially because registry metadata is untrusted input from the blockchain.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The fix command can immediately submit a signed on-chain setAgentURI transaction after computing changes, without an explicit interactive confirmation step summarizing the exact modifications and gas implications. In a wallet-bearing CLI, this increases the chance of accidental or socially engineered state changes, especially since fixes may be based on remotely fetched/untrusted metadata.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The self-check flow queries a third-party Agentscan API for all indexed agents and filters them by the configured wallet address, which expands the skill's data exposure beyond direct registry interactions. This leaks wallet ownership relationships and creates a privacy/integrity dependency on an external service whose results may be incomplete, stale, or manipulated, potentially driving users toward incorrect validation or remediation actions.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.