Back to skill

Security audit

Blockchain Web3 Toolkit

Security checks for vulnerabilities and agentic risk

Overview

This is a real blockchain toolkit, but it handles wallet secrets and irreversible on-chain actions with too little protection for safe agent use.

Review carefully before installing. Do not use this with funded wallets or production mainnet accounts unless you add secret-storage protections, remove private-key printing and default serialization, pin dependencies, and require explicit user confirmation before any deploy, mint, transfer, or state-changing transaction.

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/wallet_manager.py:30
Finding

Plaintext Private-Key Exposure Through Serialization and Console Output

Content
View full analysis

Vulnerability Details

File Location: scripts/wallet_manager.py:30-34
Additional Locations: README.md:27-32, scripts/wallet_manager.py:94-98, examples/basic_usage.py:20-24
Vulnerability Type: Plaintext handling and disclosure of wallet private keys
Risk Level: High

Vulnerable Code

scripts/wallet_manager.py:30-34:

python
def to_dict(self) -> Dict:
    return {
        "address": self.address,
        "private_key": self.private_key
    }

README.md:27-32:

python
# Create a new wallet
wallet = WalletManager.create_wallet()
print(f"Address: {wallet.address}")
print(f"Private Key: {wallet.private_key}")

# Query balance

scripts/wallet_manager.py:94-98:

python
wallet = WalletManager.create_wallet()
print(f"Address: {wallet.address}")
print(f"Private Key: {wallet.private_key[:20]}...{wallet.private_key[-10:]}")

# Validate address

examples/basic_usage.py:20-24:

python
print("\n[Step 1] Creating a new Ethereum wallet...")
wallet = WalletManager.create_wallet()
print(f"✓ Address: {wallet.address}")
print(f"✓ Private Key: {wallet.private_key[:20]}...{wallet.private_key[-10:]}")
print("  ⚠️  IMPORTANT: Save this private key securely!")

Technical Analysis

Wallet.to_dict() places the complete private key into a normal dictionary without encryption, access controls, or an explicit secret-export operation. Such dictionaries can easily be serialized, logged, sent through telemetry, included in exception diagnostics, or persisted in plaintext.

The documented quick-start example is more severe because it explicitly prints the complete private key. The executable examples also print private-key fragments. Although those fragments alone do not expose the entire key, they unnecessarily disclose secret material and encourage unsafe handling practices.

Private keys are bearer credentials: possession of the full key is su ...[truncated 1452 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove private_key from the default to_dict() output. Default serialization should contain only non-secret wallet metadata such as the public address.
  2. Replace generic plaintext export with an explicitly named operation such as export_encrypted_keystore(password).
  3. Use the Ethereum encrypted keystore format and a strong, user-supplied password with an appropriate key-derivation function.
  4. If encrypted keystores are written to disk, create files with restrictive owner-only permissions and avoid predictable temporary files.
  5. Remove all complete and partial private-key output from the README, examples, tests, and command-line demonstrations.
  6. Ensure object representations, logs, exceptions, telemetry, and debugging output redact secret values.
  7. Add tests that verify private keys are absent from default serialization and console output.
  8. Document secure backup procedures and advise users to rotate any wallet whose key may already have entered logs or plaintext storage.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned and Non-Reproducible Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-5
Additional Location: README.md:17-21
Vulnerability Type: Mutable dependency resolution without integrity verification
Risk Level: Medium

Vulnerable Code

requirements.txt:1-5:

text
web3>=6.0.0
eth-account>=0.8.0
cryptography>=3.4.8
python-dotenv>=0.19.0
requests>=2.28.0

README.md:17-21:

markdown
## Installation

```bash
pip install -r requirements.txt
text

### Technical Analysis

Every dependency uses an open-ended lower-bound constraint. A fresh installation can therefore select versions that did not exist when the project was audited, along with a changing set of transitive dependencies. No lockfile, exact version constraints, or package hashes are supplied to establish the expected dependency contents.

Python packages can execute code during installation and import. If a permitted future release or one of its transitive dependencies is compromised, the documented installation process may introduce attacker-controlled code into the user's environment. The unused direct dependency `requests` also increases the dependency and transitive supply-chain surface without providing observed project functionality.

This issue does not establish that any currently named package is malicious. The risk arises because the project cannot reproduce or verify the dependency set that was reviewed.

### Attack Path

1. A user runs the documented `pip install -r requirements.txt` command.
2. The package resolver selects the latest versions satisfying the open-ended constraints and resolves their current transitive dependencies.
3. A compromised, malicious, or unexpectedly changed future package release is selected because no reviewed version or cryptographic hash is required.
4. Package-controlled code executes during installation or when imported by the toolkit.
5. That code runs with the installing user's privi
...[truncated 668 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to an exact reviewed version rather than using unrestricted lower bounds.
  2. Generate a lockfile or compiled requirements file that also fixes all transitive dependency versions.
  3. Record and verify package hashes, and install with pip's --require-hashes option where practical.
  4. Remove requests unless it is required by actual project functionality.
  5. Perform dependency updates through a controlled review process with vulnerability scanning, changelog review, and automated tests.
  6. Use a trusted package index configuration and prevent fallback to unapproved indexes.
  7. Run installation and application execution in isolated, least-privilege environments without unrelated wallet secrets or production credentials.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (26)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The quick-start example prints a newly created wallet's private key directly to stdout, normalizing unsafe handling of a secret that grants full control over on-chain assets. In documentation for a blockchain toolkit, users may copy this pattern into scripts, terminals, logs, notebooks, or screenshots, causing irreversible compromise if the key is exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The example prints private key material directly to stdout, even if partially masked. Console output is commonly captured by terminals, shell history tools, CI logs, screen recordings, and remote session logging, so exposing any secret-derived value in example code normalizes unsafe handling and can lead to credential compromise if copied into real workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README documents contract deployment and transaction-sending capabilities without warning that blockchain transactions are irreversible, may incur real financial cost, and can affect live mainnet assets. In the context of a Web3 toolkit aimed at developers and users, omission of these warnings increases the chance of accidental loss through misuse, testing on mainnet, or unintended contract interactions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises high-risk blockchain capabilities, including wallet management, smart contract deployment, NFT minting/transfers, and gas monitoring, but provides no warning about irreversible transactions, private key sensitivity, financial loss, or the need for explicit confirmation. In this context, the omission is more dangerous because users may treat routine-looking commands as safe even though mistakes can permanently transfer assets, expose credentials, or deploy faulty contracts on-chain.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger list is broad enough to match common crypto-related discussion rather than clearly scoped operational requests, which can cause the skill to activate in contexts where the user did not intend wallet, contract, or token-related actions. In a blockchain skill, accidental invocation is especially risky because the described capabilities involve sensitive and potentially irreversible operations such as wallet management, contract deployment, and NFT transfers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Contract deployment creates, signs, and submits a real on-chain transaction without any safety disclosure or approval checkpoint, potentially consuming significant funds and deploying unreviewed bytecode permanently. In a skill/agent setting this is especially risky because deployment is a high-impact action that may be triggered programmatically from untrusted or misunderstood inputs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This method signs and broadcasts state-changing blockchain transactions immediately, with no confirmation flow, simulation, or warning that the action is irreversible and may spend funds. In an agent skill context, that is more dangerous because upstream prompts or automation could trigger real on-chain effects without the operator fully understanding the consequences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The method directly exposes a state-changing mint operation and forwards parameters to a transaction-sending interface without any built-in confirmation, policy check, or guardrail. In an agent skill context, this increases the risk of unintended on-chain asset creation if an upstream prompt, user mistake, or compromised workflow triggers the function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The transfer helper performs a state-changing NFT transfer with no local confirmation step, no recipient validation, and no friction before sending the transaction. In an agent-driven environment this is especially dangerous because a mistaken or manipulated instruction could irreversibly transfer valuable NFTs to an attacker-controlled address.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Wallet object stores and exposes the raw private key as a normal string and includes it in serialization via to_dict(), making accidental logging, persistence, transmission, or memory disclosure far more likely. In a wallet-management context this is especially dangerous because compromise of the private key directly enables theft of all assets controlled by the address.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The mnemonic import path accepts highly sensitive seed phrases and immediately derives a wallet without any safety controls, warnings, or isolation, increasing the chance that a recovery phrase is pasted into an unsafe environment, logged, or retained in process memory. Because a mnemonic can recover an entire wallet hierarchy, exposure can lead to complete compromise of multiple accounts, not just one key.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The file includes a bilingual docstring title, but all user-facing runtime messages are hardcoded in English. This can violate a language/locale policy when a skill imposes a single language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency specification uses a lower-bound version only, which permits installation of many future releases with unknown security properties and behavior. In a security-sensitive stack that includes blockchain, cryptography, and HTTP libraries, this weakens build reproducibility and can unintentionally introduce vulnerable or breaking versions.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
web3>=6.0.0
eth-account>=0.8.0
cryptography>=3.4.8
python-dotenv>=0.19.0

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
90% confidence
Finding

The manifest does not pin web3, so it is impossible to verify whether the deployed version is affected by known advisories such as SSRF-related issues in web3.py. In a blockchain-integrated skill, this uncertainty is more dangerous because web3 often processes untrusted on-chain or off-chain lookup data and may make outbound requests.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The eth-account package is unpinned and may resolve to different versions across environments or over time. Because this library handles account and signing functionality, unpredictable upgrades can expose the skill to known bugs or security regressions without any code change.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
web3>=6.0.0
eth-account>=0.8.0
cryptography>=3.4.8
python-dotenv>=0.19.0
requests>=2.28.0

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
87% confidence
Finding

Because eth-account is not pinned, the installed version may or may not include fixes for known issues such as ReDoS. This creates avoidable uncertainty in a package that may process attacker-influenced inputs during wallet or account-related operations.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

An unpinned cryptography dependency is riskier than a typical utility library because it underpins core security functions. Allowing arbitrary newer versions can pull in releases affected by crypto flaws, packaging issues, or incompatible OpenSSL builds, undermining trust in encryption and signing operations.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
web3>=6.0.0
eth-account>=0.8.0
cryptography>=3.4.8
python-dotenv>=0.19.0
requests>=2.28.0

Unverifiable Dependency: cryptography has 16 known advisory(ies) (GHSA-39hc-v87j-747x (Vulnerable OpenSSL included in cryptography wheels); CVE-2023-50782 (Python Cryptography package vulnerable to Bleichenbacher timing oracle attack); GHSA-537c-gmf6-5ccf (Vulnerable OpenSSL included in cryptography wheels) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Cryptography has a substantial advisory history, and the lack of pinning means the runtime could silently resolve to an affected build or wheel. Since this library is central to cryptographic correctness and transport security, version uncertainty materially increases the chance of serious compromise.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using python-dotenv with only a minimum version reduces reproducibility and can permit installation of releases with undiscovered or known issues. While this package is usually auxiliary, it can affect secret loading and file handling behavior in ways that matter for operational security.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
web3>=6.0.0
eth-account>=0.8.0
cryptography>=3.4.8
python-dotenv>=0.19.0
requests>=2.28.0

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The unpinned python-dotenv dependency prevents confirmation that the installed release is free from known file-handling issues. If the skill uses dotenv features to write or manage environment files, a vulnerable version could contribute to local file overwrite or secret-management risks.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Requests is a network-facing library, and leaving it unpinned can expose the application to future vulnerable releases or inconsistent behavior between deployments. Because HTTP client bugs can lead to credential leakage, SSRF-adjacent issues, or TLS handling problems, deterministic version control is important.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
eth-account>=0.8.0
cryptography>=3.4.8
python-dotenv>=0.19.0
requests>=2.28.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), 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

Requests has multiple historical advisories, and because the version is not pinned, there is no assurance the installed build includes the necessary fixes. This is especially relevant in any agent skill that performs outbound HTTP requests, where URL parsing, credential handling, and TLS behavior directly affect security.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/contract_interface.py (reported line 76)May include surrounding context.

python
abi=abi
        )
        
        func = getattr(contract.functions, function_name)
        return func(*args).call()
    
    def send_transaction(self, contract_address: str, abi: list, function_name: str, *args) -> str:

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/contract_interface.py (reported line 94)May include surrounding context.

python
abi=abi
        )
        
        func = getattr(contract.functions, function_name)
        return func(*args).call()
    
    def send_transaction(self, contract_address: str, abi: list, function_name: str, *args) -> str:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The file title and several docstrings present content bilingually, but the skill does not indicate any user language preference or opt-in mechanism. This can violate a language/locale policy where the skill should not impose a language format without user choice.

Content

No source excerpt is available for this finding.