Back to skill

Security audit

CryptoWallet - Multi-Chain Blockchain Wallet Manager

Security checks for vulnerabilities and agentic risk

Overview

This wallet skill is broadly purpose-aligned, but it handles real private keys and irreversible transactions with unsafe defaults that need careful review.

Review this before installing if you might use real funds. Avoid entering private keys or wallet passwords directly in commands, prefer a test wallet first, verify every recipient and contract manually, and do not use batch transfers or contract writes unless you fully understand the irreversible transaction being sent.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/crypto_utils.py:63
Finding
Wallet Name Path Traversal and Symbolic-Link File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crypto_utils.py:63-84` **Vulnerability Type**: Path traversal and unsafe symbolic-link following **Risk Level**: High ### Vulnerable Code ```python def save_wallet(name: str, address: str, encrypted_key: dict, chain_type: str): """Save an encrypted wallet to disk.""" wallet_file = KEYSTORE_DIR / f"{name}.json" data = { "name": name, "address": address, "chain_type": chain_type, "encrypted_key": encrypted_key } with open(wallet_file, 'w') as f: json.dump(data, f, indent=2) wallet_file.chmod(0o600) # Owner read/write only return str(wallet_file) def load_wallet(name: str) -> dict: """Load an encrypted wallet from disk.""" wallet_file = KEYSTORE_DIR / f"{name}.json" if not wallet_file.exists(): raise FileNotFoundError(f"Wallet '{name}' not found") with open(wallet_file, 'r') as f: return json.load(f) ``` Wallet names reach these functions from command-line arguments at `scripts/wallet_manager.py:82` and `scripts/wallet_manager.py:88`. ### Technical Analysis The application directly interpolates an untrusted wallet name into a filesystem path without validating its characters, resolving the resulting path, or confirming that it remains under `KEYSTORE_DIR`. A wallet name containing parent-directory components, such as `../../target`, causes the resulting path to escape the intended keystore directory. Because the `.json` suffix is appended automatically, any user-writable JSON path that can be represented relative to the keystore can be targeted. The write operation uses the ordinary `open(..., 'w')` interface. It therefore follows an existing symbolic link and truncates its target. The subsequent `chmod(0o600)` may also alter the permissions of the resolved target. The corresponding load operation has the same traversal weakness and can open JSON files outside the keystore. ### Attack Pa ...[truncated 1546 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce a strict wallet-name allowlist, for example `^[A-Za-z0-9_-]{1,64}$`. 2. Reject names containing path separators, `.` or `..` path components, control characters, and absolute paths. 3. Resolve the candidate path and verify that its parent is exactly the resolved keystore directory. 4. Create files atomically with `os.open()` and flags such as `O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW`, where supported. 5. Apply mode `0o600` at creation time rather than correcting permissions after opening the file. 6. Explicitly create and verify the keystore directory with mode `0o700`. 7. Refuse to read non-regular files and symbolic links. 8. Add tests covering absolute paths, nested traversal, symbolic links, repeated names, and race conditions. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/wallet_manager.py:79
Finding
Private Keys and Wallet Passwords Exposed Through Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/wallet_manager.py:79-90` **Additional Locations**: `scripts/token_sender.py:165-169`, `scripts/contract_interactor.py:88-95`, `SKILL.md:33-40`, `SKILL.md:69-88` **Vulnerability Type**: Sensitive information exposure through command-line arguments **Risk Level**: High ### Vulnerable Code ```python # Create command create_parser = subparsers.add_parser("create", help="Create a new wallet") create_parser.add_argument("name", help="Wallet name") create_parser.add_argument("--chain", choices=["evm", "solana"], required=True) create_parser.add_argument("--password", required=True, help="Encryption password") # Import command import_parser = subparsers.add_parser("import", help="Import existing wallet") import_parser.add_argument("name", help="Wallet name") import_parser.add_argument("--key", required=True, help="Private key") import_parser.add_argument("--chain", choices=["evm", "solana"], required=True) import_parser.add_argument("--password", required=True, help="Encryption password") ``` The same pattern is used for transaction passwords: ```python parser.add_argument("--password", required=True, help="Wallet password") ``` The documentation explicitly recommends secret-bearing commands such as: ```bash python3 scripts/wallet_manager.py import imported-wallet --chain evm --key "0x..." --password "secure-password" python3 scripts/token_sender.py my-wallet 0xRecipient 0.1 --network ethereum --password "password" ``` ### Technical Analysis Command-line arguments are not a confidential input channel. Depending on the operating system and environment, arguments may be visible through process-inspection facilities, monitoring agents, audit frameworks, job schedulers, debugging tools, terminal capture, and automation logs. Commands entered interactively are also commonly persisted in shell history. As implemented and documented, both wallet passwords and raw imported private keys are placed direc ...[truncated 1593 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--key` and `--password` as ordinary command-line options. 2. Prompt interactively with `getpass.getpass()` so passwords are neither echoed nor added to the argument vector. 3. Accept imported keys through protected standard input or a dedicated file descriptor. 4. If file-based import is necessary, require a regular file with restrictive permissions and securely remove it after use where feasible. 5. Avoid environment variables for long-lived secrets because they may also be exposed by process and diagnostic interfaces. 6. Update every example in `SKILL.md` so it no longer places secrets in commands. 7. Ensure CI systems and wrappers mask secrets and do not echo secret input. 8. Warn existing users to remove historical commands from shell histories and review terminal, automation, and audit logs for prior exposure. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unbounded Security-Critical Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-6` **Additional Location**: `SKILL.md:153-156` **Vulnerability Type**: Unpinned dependency and software supply-chain risk **Risk Level**: Medium ### Vulnerable Code ```text web3>=6.0.0 solana>=0.30.0 solders>=0.18.0 eth-account>=0.9.0 cryptography>=41.0.0 base58>=2.1.0 ``` The installation documentation also recommends unconstrained installation: ```bash pip install web3 solana solders eth-account cryptography base58 ``` ### Technical Analysis Every dependency uses a lower-bound-only constraint, allowing the package installer to select arbitrary future versions. No lockfile or package hashes are supplied. These packages execute in a highly sensitive process that decrypts private keys, creates accounts, signs transactions, and communicates with blockchain networks. A compromised future release, unexpected transitive dependency, or incompatible API change can therefore affect wallet confidentiality and transaction integrity. The reviewed package names do not themselves demonstrate typosquatting or a known malicious release. The confirmed issue is the absence of reproducible, reviewed dependency resolution. ### Attack Path 1. A user installs the project using `pip install -r requirements.txt` or follows the unconstrained documentation command. 2. The package index resolves the newest versions satisfying the broad lower bounds. 3. A compromised or otherwise unsafe future release, or one of its transitive dependencies, is selected. 4. Installation hooks or imported package code executes in the wallet environment. 5. Malicious dependency code can inspect decrypted keys in process memory, alter destination addresses or amounts, or transmit sensitive material. 6. Because installations are not hash-locked, the installed artifact cannot be reliably tied to a previously audited dependency set. ### Impact Assessment A compromised dependency executes with the same operating-system privi ...[truncated 391 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin all direct and transitive dependencies to reviewed versions in a lockfile. 2. Require cryptographic hashes for downloaded distributions, such as through a hash-locked requirements file. 3. Generate the lockfile from a controlled environment and retain it in version control. 4. Install dependencies inside an isolated virtual environment or container. 5. Use automated vulnerability and dependency-integrity scanning. 6. Review release notes and security advisories before dependency upgrades. 7. Update versions through explicit, reviewed pull requests rather than allowing installation-time resolution of arbitrary future releases. 8. Keep the documented installation procedure consistent with the locked dependency workflow. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/token_sender.py:95
Finding
Inexact Floating-Point Conversion of Cryptocurrency Transfer Amounts<![CDATA[ ## Vulnerability Details **File Location**: `scripts/token_sender.py:95` and `scripts/token_sender.py:134` **Vulnerability Type**: Numeric precision loss in financial transaction construction **Risk Level**: Medium ### Vulnerable Code ERC-20 conversion: ```python # Get decimals (assume 18 if call fails) try: decimals = contract.functions.decimals().call() except: decimals = 18 amount_raw = int(float(amount) * (10 ** decimals)) ``` Solana conversion: ```python # Build transaction amount_lamports = int(float(amount) * 1e9) transfer_ix = transfer( TransferParams( from_pubkey=keypair.pubkey(), to_pubkey=PublicKey.from_string(to_address), lamports=amount_lamports ) ) ``` ### Technical Analysis Python `float` uses binary floating-point and cannot exactly represent many decimal currency values. Converting the user-provided decimal string to `float`, multiplying by the token's decimal scale, and then applying `int()` can produce an integer one or more base units away from the intended value. `int()` truncates rather than detecting or correcting the precision error. Large values may also exceed the integer precision available in a floating-point mantissa. The code does not validate positivity, maximum amount, precision, finite values, or exact representability before signing. ### Attack Path 1. A user or calling automation supplies a decimal transfer amount. 2. The application converts the string to binary floating-point using `float(amount)`. 3. The represented value differs slightly from the supplied decimal value. 4. Multiplication by `10 ** decimals` or `1e9` amplifies the discrepancy. 5. `int()` silently truncates the result to an unintended base-unit amount. 6. The incorrectly constructed transaction is signed and broadcast without an exact base-unit confirmation. 7. Once confirmed on-chain, the amount discrepancy is generally irreversible. An attacker who controls an upstream amount field can delibera ...[truncated 588 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse amount strings with `decimal.Decimal` rather than `float`. 2. Reject NaN, infinity, negative values, zero where inappropriate, scientific notation if unsupported, and values exceeding configured transaction limits. 3. Verify that the number of fractional digits does not exceed the token's declared precision. 4. Convert exactly by multiplying the decimal value by `Decimal(10) ** decimals`. 5. Require the scaled result to be integral; reject rather than silently round or truncate. 6. Apply explicit bounds suitable for the target chain and token representation. 7. Display the normalized amount and exact integer base-unit value before signing, and require confirmation for interactive use. 8. Add boundary tests for high-precision values, very large values, one-base-unit transfers, and values immediately above or below conversion boundaries. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The code chunk’s actual behavior is much narrower than the declared description. It only implements balance querying for native tokens, ERC20 tokens, and SPL tokens via RPC calls. There is no code for generating wallets, importing private keys/seed phrases, encrypting or storing secrets, managing multiple wallets, signing transactions, broadcasting transfers, interacting with arbitrary smart contracts, handling NFTs, or providing full wallet management. The primary purpose is therefore a balance checker, not a complete cryptocurrency wallet management system. This is a material description-behavior mismatch due to significant overstatement of implemented capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description promises a comprehensive Web3 wallet platform with on-chain capabilities across many networks: creating/importing wallets, checking balances, sending tokens, interacting with contracts/DeFi, managing NFTs, and multi-chain portfolio operations. The supplied code does not implement those behaviors. It only provides local keystore utilities: PBKDF2-based key derivation, AES-GCM encryption/decryption of private keys, saving/loading wallet metadata as JSON files under the user's home directory, and listing stored wallets. While encrypted local storage is consistent with part of the description, the actual code is only a small supporting subset of the claimed functionality. Therefore the description materially overstates the behavior of this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description substantially overstates what this specific code chunk does. The implemented behavior is limited to password-based loading/decryption of an existing wallet and sending funds on supported chains: EVM native, ERC20, and Solana native SOL. The Solana path explicitly states SPL transfer is not implemented. There is also no evidence here of wallet creation/import, portfolio management, balance checks, NFT handling, or generalized smart-contract/DeFi features. While encrypted key usage is consistent with the description, the primary represented capability of 'complete cryptocurrency wallet management' is not accurately reflected by this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description significantly overstates the implemented functionality. The code only supports wallet creation, wallet import, local encrypted storage via helper functions, and listing wallets. It does not implement blockchain RPC/network interactions, token balance retrieval, transfers, smart contract calls, DeFi operations, NFT handling, or broad per-network management across the many named chains. The core purpose is related to wallet management, so the description is directionally aligned at a high level, but it is materially inaccurate as a 'complete cryptocurrency wallet management' solution because most advertised capabilities are absent from the supplied code.

Missing User Warnings

High
Confidence
95% confidence
Finding
The documentation presents send, contract-write, payable, approval, and staking examples in a routine manner without strong warnings about irreversible transfers, unlimited approvals, contract trust assumptions, phishing/token spoofing, or simulation/confirmation requirements. In a wallet skill, this materially increases the risk that users or downstream agents will execute high-impact blockchain actions without understanding that mistakes cannot be rolled back.

Missing User Warnings

High
Confidence
95% confidence
Finding
The batch transfer example shows mass sending via a shell loop without per-recipient verification, dry-run checks, or confirmation prompts. In a cryptocurrency context this is especially dangerous because a malformed recipient list, clipboard poisoning, shell expansion issue, or wrong network selection can rapidly cause irreversible loss across many transactions.

Missing User Warnings

High
Confidence
99% confidence
Finding
Accepting a private key and encryption password as command-line arguments is dangerous because process arguments are commonly exposed through shell history, process listings, audit logs, and crash reports. In a wallet-management skill handling real cryptocurrency assets, this can directly leak the raw private key or the password protecting stored key material, enabling theft of funds.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises shell, file read, and file write driven workflows but declares no explicit tool scope or permissions boundary. For a wallet-management skill that can touch encrypted key material and initiate transactions, missing least-privilege declarations increases the chance the agent is invoked with broader capabilities than necessary and makes dangerous operations harder to govern or review.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: cryptowallet
description: "Complete cryptocurrency wallet management for Web3, DeFi, and blockchain applications. Create and manage EVM (Ethereum, Polygon, BSC, Arbitrum, Optimism, Base, Avalanche) and Solana wallets with encrypted local storage. Query balances for native tokens (ETH, MATIC, BNB, SOL) and standard tokens (ERC20, SPL). Send transactions, interact with smart contracts, and manage multiple addresses across 12+ networks. Secure password-protected key storage with AES-256 encryption. Use for: (1) Creating new crypto wallets, (2) Importing existing wallets, (3) Checking token balances across chains, (4) Sending cryptocurrency and tokens, (5) Interacting with DeFi protocols and smart contracts, (6) Multi-chain portfolio management, (7) NFT transfers, (8) Blockchain development and testing. Keywords: crypto, cryptocurrency, wallet, blockchain, ethereum, solana, web3, defi, token, erc20, nft, smart contract, metamask alternative, hardware wallet, cold storage, hot wallet, blockchain wallet, digital wallet, bitcoin."
---

# CryptoWallet
Confidence
90% confidence
Finding
The skill explicitly supports encrypted local wallet storage and multi-session management of private keys and addresses. Even with encryption, session persistence of wallet material is inherently sensitive: compromise of the host, weak passwords, or accidental reuse by other workflows can expose high-value assets over time.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The manifest uses broad crypto and wallet keywords, including generic terms like bitcoin, web3, defi, nft, and metamask alternative, which can cause over-triggering for loosely related prompts. In this context, accidental invocation is more dangerous than usual because the skill supports wallet storage, transaction sending, and contract interaction, so a generic crypto request could escalate into sensitive or asset-moving operations.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The custom RPC section encourages use of third-party endpoints but omits a privacy warning that RPC operators can observe addresses, balances, contract calls, IP-associated metadata, and transaction timing. For a wallet-management skill, this can expose sensitive financial activity and targeting information even if private keys remain encrypted.

External Transmission

Medium
Category
Data Exfiltration
Content
"avalanche": {
      "name": "Avalanche C-Chain",
      "chain_id": 43114,
      "rpc": "https://api.avax.network/ext/bc/C/rpc",
      "explorer": "https://snowtrace.io",
      "native_token": "AVAX"
    },
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code sends the user-supplied wallet address to a third-party EVM RPC endpoint to retrieve balances, which leaks financial metadata and address ownership interest to external infrastructure. In a cryptocurrency wallet skill, that privacy exposure is security-relevant because RPC providers can log addresses, correlate activity across chains, and potentially deanonymize users, yet the script provides no explicit disclosure or consent mechanism.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
ERC20 balance queries disclose both the wallet address and the token contract being investigated to an external RPC service. That reveals not just the user identity target but also asset interest and portfolio composition, which is particularly sensitive in a multi-chain wallet context and is done without warning, consent, or provider transparency.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The Solana balance lookup transmits the queried wallet address to a remote Solana RPC endpoint without disclosure. For a wallet-management skill, this enables third parties to collect address lookup telemetry and correlate user behavior, reducing financial privacy and potentially exposing sensitive portfolio information.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
This script decrypts a wallet key, signs, and immediately broadcasts a state-changing transaction based on CLI inputs without any explicit confirmation, transaction preview, or policy check. In a crypto wallet skill, that is especially dangerous because a prompt-influenced or mistaken invocation can irreversibly transfer value, approve token spend, or call malicious contract functions across multiple supported networks.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The top-level docstring says the script can 'Send native tokens and ERC20/SPL tokens,' which contradicts the runtime behavior that returns 'SPL token transfer not yet implemented' and exits. This is an active documentation-to-code contradiction, not merely missing detail.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
Accepting the wallet password via a command-line argument exposes the secret to local process inspection, shell history, audit logs, and orchestration tooling. In a cryptocurrency wallet context, disclosure of the decryption password can directly enable recovery of the private key and unauthorized transfer of funds.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest describes sending 'ERC20/SPL' tokens and broad Solana wallet management, but this script exits with an error when a Solana token address is provided. That creates a direct mismatch between advertised functionality and actual implemented behavior for Solana token transfers.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The code persists encrypted private key material to disk immediately after wallet creation/import, but provides no user-facing notice that highly sensitive secrets are being stored locally. In a cryptocurrency wallet context, this increases the chance users unknowingly leave recoverable key material on shared, backed-up, or insufficiently protected systems, which can lead to wallet compromise if encryption is weak, the password is exposed, or storage permissions are lax.

Unpinned Dependencies

Low
Category
Supply Chain
Content
web3>=6.0.0
solana>=0.30.0
solders>=0.18.0
eth-account>=0.9.0
Confidence
95% confidence
Finding
The dependency uses a lower-bound specifier instead of a pinned version, which makes builds non-reproducible and can silently pull in vulnerable or breaking releases. In a cryptocurrency wallet skill that handles keys, balances, and transactions, supply-chain instability is more dangerous because compromised or incompatible blockchain libraries can directly affect wallet integrity and transaction safety.

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
92% confidence
Finding
The manifest does not pin web3, so it is impossible to determine whether deployments will include a release affected by known advisories such as the cited SSRF issue. This matters more in a Web3 wallet skill because blockchain interactions may process untrusted on-chain/off-chain metadata, increasing the chance that vulnerable URL-handling paths could be reached.

Unpinned Dependencies

Low
Category
Supply Chain
Content
web3>=6.0.0
solana>=0.30.0
solders>=0.18.0
eth-account>=0.9.0
cryptography>=41.0.0
Confidence
94% confidence
Finding
Using solana with only a minimum version allows future installs to resolve to unreviewed releases, which increases supply-chain and stability risk. Because this skill manages crypto wallets and may sign or submit blockchain transactions, an unexpected dependency change could lead to denial of service, incorrect transaction handling, or exposure to malicious package behavior.

Unpinned Dependencies

Low
Category
Supply Chain
Content
web3>=6.0.0
solana>=0.30.0
solders>=0.18.0
eth-account>=0.9.0
cryptography>=41.0.0
base58>=2.1.0
Confidence
93% confidence
Finding
The solders package is unpinned, so installations are not reproducible and may consume a later vulnerable or incompatible release. In a crypto-wallet context, low-level serialization/signing dependencies are sensitive because defects or malicious changes can corrupt key handling or transaction construction.

Unpinned Dependencies

Low
Category
Supply Chain
Content
web3>=6.0.0
solana>=0.30.0
solders>=0.18.0
eth-account>=0.9.0
cryptography>=41.0.0
base58>=2.1.0
Confidence
96% confidence
Finding
eth-account is unpinned, so future installations may resolve to versions with known flaws or behavioral changes. This is especially risky here because eth-account is directly involved in account and signing operations, making any dependency compromise potentially impactful to private-key usage and transaction authorization.

Static analysis

No suspicious patterns detected.