Back to skill

Security audit

Smart Contract Audit

Security checks for vulnerabilities and agentic risk

Overview

The skill is a legitimate smart-contract audit workflow, but it can run untrusted project build code and unpinned installers on the host without clear containment.

Install only if you are comfortable running it in an isolated disposable environment. Do not run it directly on your main machine or with valuable environment variables, wallets, SSH agents, cloud credentials, or private repos accessible. Prefer a container or VM with pinned tools, no inherited secrets, limited network access, and explicit approval before any build, coverage, npx, forge, pip, cargo, npm, or curl-to-shell step.

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

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install-tools.sh:25
Finding
Mutable remote installer content is recommended for direct shell execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install-tools.sh:25-30`, `scripts/install-tools.sh:47-63` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```bash # --- Forge check --- if command -v forge &>/dev/null; then echo "✅ Forge already installed: $(forge --version 2>&1 | head -1)" else echo "⚠️ Forge not found. Install via: curl -L https://foundry.paradigm.xyz | bash && foundryup" fi ``` ```bash # --- Aderyn --- if command -v aderyn &>/dev/null; then echo "✅ Aderyn already installed: $(aderyn --version 2>&1 | head -1)" else echo "📦 Installing Aderyn..." if command -v cargo &>/dev/null; then cargo install aderyn elif [ -f "$HOME/.cargo/env" ]; then source "$HOME/.cargo/env" cargo install aderyn else echo "⚠️ Rust/cargo not found. Install Rust first:" echo " curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y" echo " source ~/.cargo/env && cargo install aderyn" fi fi ``` ### Technical Analysis The script does not automatically execute the two `curl | shell` pipelines; it prints them as installation instructions when Foundry or Rust is unavailable. Nevertheless, following those instructions passes mutable network responses directly to a command interpreter without first verifying a pinned version, cryptographic signature, or checksum. HTTPS protects the connection in transit but does not establish that the returned script is immutable or that a compromised upstream host cannot deliver a malicious response. The effective payload can change after the Skill package has been reviewed. The Foundry command also does not restrict the protocol and minimum TLS version as the Rust command does, although such restrictions would not eliminate the underlying pipe-to-shell risk. This behavior is not necessary for the Skill's core auditing function. Tools can be installed from pinned, indep ...[truncated 1281 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all pipe-to-shell installation recommendations. 2. Pin exact Foundry and Rust toolchain versions that have been reviewed. 3. Download release artifacts to a temporary file rather than executing streamed responses. 4. Verify artifacts using a publisher signature or an independently pinned SHA-256 checksum. 5. Display the artifact source, expected version, and checksum before installation. 6. Require explicit user approval before executing any downloaded file. 7. Prefer a prebuilt, reproducible audit container containing the required pinned tools. 8. If a required tool is unavailable, continue with partial analysis rather than encouraging immediate remote execution. A safer conceptual workflow is: ```bash curl --proto '=https' --tlsv1.2 --fail --location \ --output /tmp/pinned-installer.sh \ 'https://trusted.example/releases/exact-version/installer.sh' printf '%s %s\n' "$EXPECTED_SHA256" /tmp/pinned-installer.sh | sha256sum --check - less /tmp/pinned-installer.sh bash /tmp/pinned-installer.sh ``` The expected checksum must be pinned in reviewed code or obtained through a separately authenticated channel, not fetched from the same mutable endpoint as the artifact. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run-slither.sh:22
Finding
Automatic Hardhat compilation executes code controlled by an untrusted audit target<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run-slither.sh:22-25`, `scripts/run-aderyn.sh:21-24` **Vulnerability Type**: Execution of untrusted project configuration **Risk Level**: High ### Vulnerable Code In `scripts/run-slither.sh:22-25`: ```bash elif [ -f "$TARGET/hardhat.config.js" ] || [ -f "$TARGET/hardhat.config.ts" ]; then FRAMEWORK="hardhat" echo "📦 Detected Hardhat project — compiling with hardhat first..." (cd "$TARGET" && npx hardhat compile 2>/dev/null) || echo "⚠️ hardhat compile failed" ``` In `scripts/run-aderyn.sh:21-24`: ```bash elif [ -f "$TARGET/hardhat.config.js" ] || [ -f "$TARGET/hardhat.config.ts" ]; then echo "📦 Detected Hardhat project — compiling first..." (cd "$TARGET" && npx hardhat compile 2>/dev/null) || echo "⚠️ hardhat compile failed" fi ``` Related workflow instructions also permit cloning a user-selected repository and running Hardhat coverage: ```markdown - **GitHub repo:** Clone it first with `git clone` ``` ```bash npx hardhat coverage 2>/dev/null ``` ### Technical Analysis A Hardhat configuration file is executable JavaScript or TypeScript, not passive build metadata. Running `npx hardhat compile` loads the target repository's `hardhat.config.js` or `hardhat.config.ts`, along with imported modules and configured plugins. Because the repository is the subject of a security audit, its contents must be considered untrusted. A malicious repository can place arbitrary Node.js operations in its Hardhat configuration. Those operations execute before compilation and inherit the audit process's filesystem, environment, and network access. The workflow's support for cloning a user-specified GitHub repository makes this path directly reachable by an attacker who supplies a malicious audit target. Redirecting stderr to `/dev/null` does not provide isolation and can conceal warning signs. The same unsafe compile action is performed independently by both analyzer wrappers, potential ...[truncated 1653 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every audit target as hostile by default. 2. Do not automatically run Hardhat, Foundry build scripts, tests, deployment scripts, or package lifecycle hooks on the host. 3. Default to source-only static analysis when safe compilation cannot be guaranteed. 4. Require explicit informed approval before executing target-controlled build configuration. 5. Run compilation in an ephemeral sandbox with: - A non-root, disposable user. - No host credentials or inherited secrets. - A minimal allowlisted environment. - Network access disabled by default. - A read-only mount of the target source. - A separate writable output directory. - CPU, memory, process, disk, and execution-time limits. - No access to the host Docker socket, SSH agent, home directory, or cloud metadata services. 6. Use preinstalled, version-pinned Hardhat and Node.js binaries rather than allowing `npx` to dynamically retrieve packages. 7. Install dependencies with lockfile enforcement and lifecycle scripts disabled where practical. 8. Preserve and review stderr rather than discarding it. 9. Ensure the two parallel analyzers share a single isolated build result instead of independently executing configuration. 10. Apply equivalent containment to `npx hardhat coverage`, `forge build`, `forge coverage`, and generated PoC tests because target-controlled build hooks and imports may also execute during those operations. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/install-tools.sh:32
Finding
Unpinned analysis tools are installed into the host environment<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install-tools.sh:32-57` **Vulnerability Type**: Unpinned and globally scoped third-party dependencies **Risk Level**: Medium ### Vulnerable Code ```bash # --- Slither --- if command -v slither &>/dev/null; then echo "✅ Slither already installed: $(slither --version 2>&1 | head -1)" else echo "📦 Installing Slither..." pip3 install --break-system-packages slither-analyzer 2>/dev/null || pip3 install slither-analyzer fi # --- solc-select --- if command -v solc-select &>/dev/null; then echo "✅ solc-select already installed" else echo "📦 Installing solc-select..." pip3 install --break-system-packages solc-select 2>/dev/null || pip3 install solc-select fi # --- Aderyn --- if command -v aderyn &>/dev/null; then echo "✅ Aderyn already installed: $(aderyn --version 2>&1 | head -1)" else echo "📦 Installing Aderyn..." if command -v cargo &>/dev/null; then cargo install aderyn elif [ -f "$HOME/.cargo/env" ]; then source "$HOME/.cargo/env" cargo install aderyn ``` Additional unsafe installation guidance appears in `references/tool-guide.md:15-18`, `references/tool-guide.md:67-73`, and `references/tool-guide.md:115-117`: ```bash pip3 install slither-analyzer pip3 install solc-select cargo install aderyn npm install -g aderyn npx @4naly3er/cli . --output 4naly3er-report.md ``` ### Technical Analysis The package names are installed without exact version constraints, hashes, signatures, or a reviewed lockfile. Consequently, every execution can resolve a different release and transitive dependency graph. The Python commands first use `--break-system-packages`, which bypasses the protection for externally managed Python environments. This can modify system-level or distribution-managed Python state rather than creating an isolated environment. The fallback installation is also not explicitly scoped to a virtual environment. Likewise, `cargo in ...[truncated 1920 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin exact versions of every directly installed tool. 2. Pin and verify transitive dependencies using ecosystem-appropriate lockfiles and hash checking. 3. Install Python tools in a dedicated virtual environment: ```bash python3 -m venv .audit-tools-venv .audit-tools-venv/bin/python -m pip install \ --require-hashes \ --requirement requirements-audit-tools.txt ``` 4. Remove `--break-system-packages` entirely. 5. Install Rust tools at reviewed versions and use locked dependency resolution where supported. 6. Replace global npm installation and dynamic `npx` retrieval with a local, lockfile-controlled dependency installation. 7. Verify package provenance and signatures where the package ecosystem supports them. 8. Prefer a reproducible, versioned container image whose digest is pinned rather than installing tools during every audit. 9. Run installation and analysis under a non-root account with no credentials and restricted network access. 10. Record exact tool and compiler versions in each audit report to make results reproducible. 11. Fail safely or continue with available tools when verification fails; do not silently fall back to an unverified installation method. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents the skill as an active smart contract auditing and analysis system. However, this code chunk only installs or verifies prerequisite tools and prints informational notes. While installing Slither/Aderyn is related to the broader domain, the actual behavior is setup/bootstrapping, not vulnerability analysis. This is a material mismatch in primary purpose and implemented capabilities.

External Script Fetching

High
Category
Supply Chain
Content
if command -v forge &>/dev/null; then
    echo "✅ Forge already installed: $(forge --version 2>&1 | head -1)"
else
    echo "⚠️  Forge not found. Install via: curl -L https://foundry.paradigm.xyz | bash && foundryup"
fi

# --- Slither ---
Confidence
95% confidence
Finding
The script recommends a classic curl-to-shell installation flow for Foundry, which executes remote code fetched at runtime without pinning or independent verification. If the remote endpoint, transport, or distribution channel were compromised, users could execute attacker-controlled code on their systems with the privileges of the current user.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill invokes shell commands (`bash`, `git clone`, `forge`, `npx hardhat`) but does not declare any explicit tool scope such as `permissions` or `allowed-tools`. In an agent setting, missing tool scoping weakens least-privilege boundaries and can allow broader-than-expected command execution if the runtime infers or permits shell access implicitly.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The skill description uses very broad trigger language such as 'use when reviewing, auditing, or analyzing smart contracts,' which can cause over-invocation in common requests. In agent ecosystems, overly broad routing increases the chance that a high-privilege skill with shell access is selected in contexts where a narrower, safer skill would suffice.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
The skill runs `npx hardhat coverage`, which resolves and executes packages from the Node ecosystem without any version pinning shown in the skill. This creates supply-chain risk and non-reproducible behavior, since a different or compromised package version could be fetched and executed at runtime.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
A second unpinned `npx hardhat` invocation appears later in the workflow, repeating the same supply-chain and reproducibility risk. Repeated unpinned runtime package execution increases exposure because the skill may fetch or run unintended versions during audit execution.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
### Bad Incentive Patterns (Red Flags for Auditors)
- "The contract will check prices every hour" → WHO pays gas? WHY?
- "Expired listings get automatically removed" → Nothing is automatic
- "The protocol rebalances daily" → Whose gas? What profit?
- "An admin will manually trigger the next phase" → Single point of failure
Confidence
80% confidence
Finding
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.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
### SC06: Unchecked External Calls
**What:** Failures, reverts, or callbacks from external contracts not handled.
**Look for:**
- Low-level `call()` without checking return bool
- Missing `try/catch` on external calls
- ERC20 `transfer()` without `SafeERC20`
- No contract existence check before `delegatecall`
Confidence
75% confidence
Finding
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.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
The script invokes `npx hardhat compile` without pinning the package version or constraining resolution to a trusted local dependency. If the target project lacks a locked local Hardhat installation, `npx` may resolve or fetch an unexpected package/version from the registry, causing execution of untrusted code during analysis. In the context of a smart-contract audit skill that processes third-party repositories, this is more dangerous because the script is expected to run inside potentially adversarial project directories.

Excessive Permissions

Low
Category
Privilege Escalation
Content
- Missing `initializer` modifier / can call `initialize()` twice
- Function selector clashes
- `selfdestruct` in implementation
- Missing upgrade access controls
**Code pattern:** `delegatecall`, `initializer`, `_disableInitializers()`
Confidence
80% confidence
Finding
Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

External Script Fetching

Low
Category
Supply Chain
Content
cargo install aderyn
    else
        echo "⚠️  Rust/cargo not found. Install Rust first:"
        echo "   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"
        echo "   source ~/.cargo/env && cargo install aderyn"
    fi
fi
Confidence
91% confidence
Finding
The script prints guidance to install Rust using a remote shell script from rustup.rs, which has the same supply-chain risk pattern as any curl-to-sh installer. Although it is only echoed and not automatically executed by this script, the skill context encourages users to run it manually, so a compromise of the remote installer could still lead to arbitrary code execution.