Back to skill

Security audit

ChaosChain - Agent Trust & Reputation

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does the advertised ChaosChain lookup work, but it also signs and broadcasts blockchain registration transactions with a configured private key while under-warning users about mainnet risk.

Install only if you are comfortable with a skill that can submit an on-chain registration transaction. Use read-only commands without configuring a private key when possible, prefer a dedicated low-balance wallet, avoid mainnet registration until the warning/confirmation bug is fixed, and review or pin dependencies before running setup in an environment that contains wallet secrets.

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/chaoschain_skill.py:568
Finding
Mainnet Registration Is Incorrectly Presented as a Testnet Transaction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chaoschain_skill.py:185-188` and `scripts/chaoschain_skill.py:568-579` **Vulnerability Type**: Incorrect network classification and missing transaction confirmation **Risk Level**: High ### Vulnerable Code ```python NETWORK_ALIASES = { "mainnet": "ethereum_mainnet", "sepolia": "ethereum_sepolia", } ``` ```python # Extra warning for mainnet if config["network"] == "mainnet": print("🔴 MAINNET TRANSACTION - REAL ETH REQUIRED") print("") print("You are about to register on Ethereum Mainnet.") print("This costs real ETH and is permanent.") print("") print("For testing, use: /chaoschain register --network sepolia") print("") else: print(f"Network: {config['network'].upper()} (testnet)") print("") ``` ### Technical Analysis Network aliases are normalized before registration. The `mainnet` alias becomes `ethereum_mainnet`, but the warning condition subsequently compares the normalized value against the unreachable string `mainnet`. Consequently, `config["network"] == "mainnet"` is false for Ethereum mainnet. It is also false for every other supported mainnet identifier, such as `base_mainnet` and `polygon_mainnet`. These networks therefore enter the `else` branch and are explicitly labeled as testnets. The registration flow does not request an interactive confirmation after displaying this incorrect classification. If a private key and sufficient funds are configured, the Skill proceeds to build, locally sign, and broadcast the transaction. ### Attack Path 1. A user configures `CHAOSCHAIN_NETWORK=mainnet` or invokes: ```bash /chaoschain register --network mainnet ``` 2. The alias parser normalizes `mainnet` to `ethereum_mainnet`. 3. The registration warning checks whether `config["network"]` equals `mainnet`. 4. The condition fails because the value is `ethereum_mainnet`. 5. The Skill displays `ETHEREUM_MAINNET (testnet)` instead of the real-fun ...[truncated 808 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Represent network type explicitly in each network configuration: ```python "ethereum_mainnet": { ... "is_mainnet": True, } ``` Then use: ```python if config["is_mainnet"]: ... ``` 2. Alternatively, classify normalized identifiers consistently: ```python is_mainnet = config["network"].endswith("_mainnet") ``` An explicit configuration field is preferable because it avoids reliance on naming conventions. 3. Require affirmative confirmation before broadcasting any registration transaction. For noninteractive use, require an explicit flag such as `--yes`, and require an additional mainnet-specific acknowledgement such as: ```bash --confirm-mainnet ``` 4. Display the chain ID, RPC host, registry address, estimated maximum gas cost, and wallet address before requesting confirmation. 5. Treat every non-testnet network as production rather than placing unknown networks in a generic testnet branch. 6. Add automated tests for aliases and every supported network, verifying that all `*_mainnet` networks receive a real-funds warning and all testnets receive the correct label. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:4
Finding
Unpinned Dependencies Permit Unreviewed Supply-Chain Updates<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:4-5` and `scripts/setup.sh:21-23` **Vulnerability Type**: Unbounded dependency resolution and non-reproducible installation **Risk Level**: Medium ### Vulnerable Code ```text web3>=6.0.0 eth-account>=0.8.0 ``` ```bash # Activate and install dependencies echo "📚 Installing dependencies..." source "$SKILL_DIR/.venv/bin/activate" pip install --quiet --upgrade pip pip install --quiet -r "$SKILL_DIR/requirements.txt" ``` ### Technical Analysis The dependency manifest specifies only minimum versions. Any future release of `web3` or `eth-account` satisfying those lower bounds can therefore be installed, along with unconstrained transitive dependencies. The setup script also upgrades pip to the latest available version before resolving the requirements. These mutable installation steps prevent reproducible builds and expand the code executed from external package repositories beyond versions reviewed with the Skill. This is not evidence that the named packages are currently malicious. The vulnerability is the absence of version and integrity constraints around third-party code that executes with the installing user’s permissions. This is especially sensitive because the resulting environment later handles `CHAOSCHAIN_PRIVATE_KEY`. ### Attack Path 1. A direct or transitive dependency publishes a compromised or otherwise unsafe release that still satisfies the broad version constraints. 2. A user follows the documented setup procedure and runs: ```bash ./scripts/setup.sh ``` 3. pip queries its configured package index and resolves the new compatible release. 4. The package and its transitive dependencies are downloaded without an expected-hash check. 5. Package installation or later import executes attacker-controlled code with the user’s local permissions. 6. When the user invokes `whoami` or `register`, malicious dependency code running in the same process may access environment ...[truncated 805 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a reviewed lock file containing exact direct and transitive versions. 2. Add cryptographic hashes for every resolved artifact and install with: ```bash pip install --require-hashes -r requirements.lock ``` 3. Replace broad lower bounds with exact reviewed versions in the deployment manifest. For example: ```text web3==<reviewed-version> eth-account==<reviewed-version> ``` The actual versions must be selected after compatibility and vulnerability review. 4. Remove the unconditional pip upgrade. Pin the installer version separately when an upgrade is required: ```bash python -m pip install --require-hashes -r bootstrap-requirements.txt ``` 5. Use `python -m pip` from the selected virtual environment rather than relying on PATH resolution. 6. Apply automated dependency vulnerability scanning and a controlled update process. Regenerate hashes and rerun tests whenever dependencies are upgraded. 7. Keep wallet credentials outside the environment used for dependency installation, and prefer an external signer or restricted signing interface so imported Python packages never receive direct access to the raw private key. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Intent-Code Divergence

High
Confidence
96% confidence
Finding
The README prominently markets the skill as 'READ-ONLY by Default' and 'No transactions, no custody, no risk' while also documenting a /register command that performs on-chain transactions and requires a private key. This can mislead users into installing or configuring the skill under a false sense of safety, increasing the chance they expose credentials or authorize blockchain actions they did not expect.

Description-Behavior Mismatch

High
Confidence
94% confidence
Finding
The skill metadata and description imply a verification-only capability, but the documented behavior also includes agent registration on-chain. That mismatch can cause operators, reviewers, or automated policy systems to classify the skill as lower risk than it actually is, which is dangerous in a context where the skill may request sensitive key material and submit transactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Although the documentation mentions registration later, the declared purpose remains verification-focused while the skill materially acts as a launcher for an on-chain registration workflow. In an agent ecosystem, this context makes the issue more dangerous because verification tools are likely to be treated as low-risk, yet this one can trigger irreversible blockchain actions and consume funds for gas.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Although the documentation mentions registration later, the declared purpose remains verification-focused while the skill materially acts as a launcher for an on-chain registration workflow. In an agent ecosystem, this context makes the issue more dangerous because verification tools are likely to be treated as low-risk, yet this one can trigger irreversible blockchain actions and consume funds for gas.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The module docstring explicitly claims 'READ-ONLY access' and 'No protocol execution, no payments,' yet the command list includes `register` and the code later builds, signs, and broadcasts a nonpayable transaction. In an agent-skill ecosystem, deceptive safety claims materially increase risk because orchestration layers and users may trust the skill with wallet secrets or permit autonomous execution based on inaccurate documentation.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill metadata and top-level description frame the tool as verification-focused, but the implementation includes a write-capable `register` command that signs and submits blockchain transactions using `CHAOSCHAIN_PRIVATE_KEY`. This mismatch is dangerous because users or higher-level agents may grant permissions or invoke the skill under the false assumption that it is read-only, leading to unintended on-chain actions and gas expenditure.

Intent-Code Divergence

Medium
Confidence
81% confidence
Finding
The README's 'What This Is NOT' section states the skill does not interact with ChaosChain Gateway, but elsewhere the same document advertises `/chaoschain register`, requires `CHAOSCHAIN_PRIVATE_KEY`, and warns that registration enables on-chain transactions. This is an intent-level contradiction in the documentation because the skill is presented both as non-interacting beyond read-only verification and as capable of state-changing registration behavior.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill advertises shell and environment-dependent behavior (`setup.sh`, wallet env vars, Python execution) but declares no explicit tool scope or permissions. That creates hidden capability risk: an agent or user may invoke a skill with broader execution and secret access than the metadata signals, undermining informed consent and policy enforcement.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
python_exe = sys.executable

args = [python_exe, main_script, "whoami"] + sys.argv[1:]
sys.exit(subprocess.call(args))
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
python_exe = sys.executable

args = [python_exe, main_script, "whoami"] + sys.argv[1:]
sys.exit(subprocess.call(args))
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
python_exe = sys.executable

args = [python_exe, main_script, "whoami"] + sys.argv[1:]
sys.exit(subprocess.call(args))
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
python_exe = sys.executable

args = [python_exe, main_script, "whoami"] + sys.argv[1:]
sys.exit(subprocess.call(args))
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# ChaosChain OpenClaw Skill Dependencies
# Minimal dependencies for trust verification

web3>=6.0.0
eth-account>=0.8.0
Confidence
98% confidence
Finding
The dependency specifier `web3>=6.0.0` is unpinned, so installs may resolve to different versions over time, undermining reproducibility and allowing accidental adoption of vulnerable or breaking releases. In a security-sensitive skill that performs blockchain identity and trust verification, silently drifting to an affected `web3` version could expose the agent to known library flaws or change verification behavior unexpectedly.

Unverifiable Dependency: web3 has 2 known advisory(ies) (CVE-2026-40072 (web3.py: SSRF via CCIP Read (EIP-3668) OffchainLookup URL handling); CVE-2026-40072 (web3.py: SSRF via CCIP Read (EIP-3668) OffchainLookup URL handling)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding
The manifest does not pin `web3`, and static analysis notes known advisories including SSRF in CCIP Read/OffchainLookup URL handling. In a skill that verifies AI agent identity and reputation via on-chain registries, using a vulnerable `web3` release could let crafted on-chain data trigger server-side network requests, potentially reaching internal services or exfiltrating metadata depending on deployment.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# Minimal dependencies for trust verification

web3>=6.0.0
eth-account>=0.8.0
Confidence
98% confidence
Finding
The dependency specifier `eth-account>=0.8.0` is unpinned, which permits non-deterministic dependency resolution and makes it hard to verify whether deployed environments are using a safe version. Because this skill handles on-chain identity/reputation verification, dependency drift in account-handling code can introduce denial-of-service or parsing weaknesses into a trust-sensitive workflow.

Unverifiable Dependency: eth-account has 2 known advisory(ies) (CVE-2022-1930 (Regular expression denial of service in eth-account); CVE-2022-1930 (Regular expression denial of service in eth-account)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
The manifest does not pin `eth-account`, and the package has known advisory history for regular expression denial of service. Even if exploitability depends on how the library is used, leaving the version unconstrained means deployments may resolve to an affected release, allowing attacker-controlled inputs to consume excessive CPU and degrade availability in identity verification flows.

Static analysis

No suspicious patterns detected.