Back to skill

Security audit

AI Walllet Payment System

Security checks for vulnerabilities and agentic risk

Overview

This wallet skill is not clearly malicious, but it handles real cryptocurrency transactions with serious implementation and documentation risks that could lead to fund loss.

Treat this as a Review item, not as proven malware. Do not install it for production, mainnet, or meaningful funds unless the transaction flow, key recovery design, dependency pins, HSM claims, and documentation are fixed and independently audited. If testing, use an isolated virtual environment, testnet-only funds, a trusted RPC provider, and assume generated wallets may become unrecoverable.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:1314
Finding
Time-Dependent Key Derivation Makes Private Keys Undecryptable<![CDATA[ ## Vulnerability Details **File Location**: `ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:1314-1330`, with vulnerable use at lines `1585` and `1618` **Vulnerability Type**: Non-deterministic cryptographic key derivation **Risk Level**: Critical ### Vulnerable Code ```python def derive_key(self, purpose: str, context: Optional[bytes] = None) -> bytes: """Derive purpose-specific key using HKDF""" # Check if rotation needed self._check_rotation() info = f"{purpose}:{time.time()}".encode('utf-8') if context: info += context hkdf = HKDF( algorithm=hashes.SHA512(), length=MaxSecurityConfig.KEY_SIZE, salt=self.salt, info=info, backend=default_backend() ) derived_key = hkdf.derive(self.master_key) return derived_key ``` The method is independently called when encrypting and decrypting wallet keys: ```python # During wallet creation encryption_key = self.key_manager.derive_key("wallet_encryption") ``` ```python # During private-key decryption encryption_key = self.key_manager.derive_key("wallet_encryption") ``` ### Technical Analysis HKDF deterministically returns the same key only when its input key material, salt, context, and `info` are identical. The implementation includes `time.time()` in the HKDF `info` field. Because the encryption and decryption calls occur at different times, they derive different keys. ChaCha20-Poly1305 authentication will consequently reject the stored ciphertext during decryption. This failure occurs even within the same application process and does not require a restart, key rotation, or an external attacker. ### Attack Path 1. A user initializes the wallet API. 2. `create_wallet()` derives an encryption key using the current timestamp. 3. The generated Ethereum private key is encrypted and the ciphertext is stored. 4. The user later calls `send_transaction()`. 5. `decrypt_private_key()` invokes `derive_key("wallet_enc ...[truncated 712 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove all transient values, including `time.time()`, from cryptographic key derivation. - Use a fixed, versioned purpose label such as `b"wallet-encryption:v1"`. - Include a persisted, cryptographically random wallet-specific salt or identifier as the derivation context. - Store the key-derivation version and salt alongside each encrypted wallet record. - Bind the ciphertext to the wallet identifier and key version through ChaCha20-Poly1305 associated data. - Add automated tests that verify: - Encryption and decryption round trips in the same process. - Decryption after process restart. - Decryption after opening an existing database. - Correct behavior during key migration and rotation. - Do not permit wallet addresses to be displayed for funding until a recovery test has successfully decrypted and validated the corresponding private key. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:1298
Finding
Ephemeral Master-Key Parameters Prevent Database Recovery After Restart or Rotation<![CDATA[ ## Vulnerability Details **File Location**: `ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:1298-1303`, with related rotation and database use at lines `1345-1356` and `1690-1692` **Vulnerability Type**: Non-persistent key derivation state and destructive key rotation **Risk Level**: Critical ### Vulnerable Code ```python # Generate unique salt for this instance self.salt = secrets.token_bytes(MaxSecurityConfig.SALT_SIZE) # Derive master key try: hash_result = self.hasher.hash(master_password) # Extract just the hash part (after the last $) self.master_key = hash_result.split('$')[-1].encode('utf-8')[:32] except Exception as e: raise CryptographicException(f"Key derivation failed: {type(e).__name__}") ``` The HKDF salt is replaced during rotation without re-encrypting existing data: ```python def _rotate_keys(self): """Rotate encryption keys""" logging.info("🔄 Rotating encryption keys...") # Generate new salt new_salt = secrets.token_bytes(MaxSecurityConfig.SALT_SIZE) # Wipe old salt self.memory_manager.secure_wipe(self.salt) self.salt = new_salt self.last_rotation = time.time() logging.info("✓ Keys rotated successfully") ``` The resulting transient key is used to open the persistent database: ```python db_key = self.key_manager.derive_key("database_encryption") db_path = Path("data/ultra_secure.db") self.db = EncryptedDatabase(db_path, db_key) ``` ### Technical Analysis `argon2.PasswordHasher.hash()` generates a new random salt for each invocation. The code extracts part of the newly generated encoded hash and uses it as the master key. It also generates a separate random HKDF salt in `self.salt`. Neither value is persisted in a recoverable key envelope. Reinitializing the program with the same password therefore produces unrelated key material. The existing SQLCipher database cannot reliably be reopened. The rotation routine introduces an additional destructive failure: ...[truncated 1468 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Use a dedicated password KDF such as Argon2id with an explicitly generated and persisted salt. - Persist the KDF salt, algorithm identifier, version, memory cost, time cost, and parallelism outside the encrypted payload. - Derive the same key from the same password and persisted parameters on every launch. - Do not extract bytes by truncating the textual Argon2 encoded-hash representation. Use a raw key-derivation API designed to return key bytes. - Store a randomly generated database encryption key in an authenticated key envelope protected by the password-derived key. - Implement versioned, transactional key rotation: 1. Retain the old key. 2. Generate the new key. 3. Re-encrypt every record. 4. Verify every migrated record. 5. Atomically commit the new key version. 6. Erase the old key only after successful verification. - Implement and test encrypted backup and recovery rather than merely requiring an unused fingerprint environment variable. - Add restart, password verification, backup restoration, and interrupted-rotation tests. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:1194
Finding
TPM Presence Is Incorrectly Treated as Functional HSM Protection<![CDATA[ ## Vulnerability Details **File Location**: `ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:1194-1265` **Vulnerability Type**: Security-control spoofing and insecure cryptographic fallback **Risk Level**: High ### Vulnerable Code ```python def _check_hsm_availability(self) -> bool: """Check if HSM is available""" # In production: Check for actual HSM # For now, we'll check if we're in a secure environment try: # Check for TPM tpm_present = Path('/dev/tpm0').exists() or Path('/dev/tpmrm0').exists() # Check for YubiHSM # yubihsm_present = self._check_yubihsm() # Check for AWS CloudHSM # cloudhsm_present = self._check_cloudhsm() return tpm_present # or yubihsm_present or cloudhsm_present except Exception: return False ``` When this test succeeds, the purported HSM operation still uses ordinary process memory: ```python def generate_key(self, key_type: str = 'AES256') -> bytes: """Generate key in HSM""" if self.available: # In production: Use HSM to generate key logging.info("Generating key in HSM") return secrets.token_bytes(32) else: # Fallback to secure software generation logging.warning("HSM not available, using software key generation") return secrets.token_bytes(32) def encrypt(self, plaintext: bytes, key_id: str) -> bytes: """Encrypt using HSM""" if self.available: # In production: Use HSM encryption logging.info(f"Encrypting with HSM key: {key_id}") # Fallback for demo return self._software_encrypt(plaintext) else: return self._software_encrypt(plaintext) ``` ### Technical Analysis A TPM device node is not evidence that an HSM-backed key has been provisioned, authorized, or used. The implementation treats the existence of `/dev/tpm0` or `/dev/tpmrm0` as successful HSM availability. Even when `available` is true, keys are g ...[truncated 1305 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not treat TPM device-node presence as HSM availability. - Integrate a supported HSM or TPM API and perform an authenticated capability check. - Generate non-exportable signing keys inside the hardware boundary. - Perform Ethereum signing through the hardware interface without returning the raw private key to Python. - Verify device identity, key identifiers, authorization policies, and expected firmware or attestation state. - If `REQUIRE_HSM` is enabled, remove all software fallback paths and fail closed. - Clearly distinguish TPM, HSM, secure-enclave, and software-key capabilities in configuration and documentation. - Add integration tests proving that hardware-backed private keys cannot be exported and that signing fails when the configured device is unavailable. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:1858
Finding
Configured Transaction Security Limits Are Not Enforced<![CDATA[ ## Vulnerability Details **File Location**: `ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:704-713`, with transaction execution at lines `1858-1877` **Vulnerability Type**: Missing transaction-policy enforcement and excessive trust in the RPC provider **Risk Level**: High ### Vulnerable Code The configuration declares transaction restrictions: ```python # Transaction security (ULTRA PARANOID) MAX_TRANSACTION_AMOUNT: Final[float] = 0.1 MIN_CONFIRMATIONS: Final[int] = 50 TRANSACTION_TIMEOUT: Final[int] = 600 MAX_GAS_PRICE_GWEI: Final[int] = 100 REQUIRE_MANUAL_GAS_APPROVAL: Final[bool] = True ENABLE_TRANSACTION_SIMULATION: Final[bool] = True REQUIRE_MULTI_SIG_ABOVE_THRESHOLD: Final[bool] = True MULTI_SIG_THRESHOLD: Final[float] = 0.05 ``` The transaction path does not enforce most of these controls: ```python # Get gas price gas_price = self.w3.eth.gas_price # Build transaction amount_wei = self.w3.to_wei(amount, 'ether') transaction = { 'nonce': self.w3.eth.get_transaction_count(wallet['address']), 'to': to_address, 'value': amount_wei, 'gas': 21000, 'gasPrice': gas_price, 'chainId': self.w3.eth.chain_id } # Sign transaction signed_tx = account.sign_transaction(transaction) # Send transaction tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction) ``` ### Technical Analysis The implementation retrieves `gas_price`, nonce, and chain ID from the configured RPC endpoint and signs the transaction without: - Checking `MAX_GAS_PRICE_GWEI`. - Requiring manual gas approval. - Simulating the transaction. - Applying multisignature above `MULTI_SIG_THRESHOLD`. - Pinning the expected chain ID. - Waiting for the configured `MIN_CONFIRMATIONS`. The provider URL is only checked for an `https://` prefix. Therefore, a compromised, malicious, or incorrectly configured RPC provider can supply hostile transaction parameters, particularly an excessive gas price or an unexpected chain ID. Signed Ethereum transactions do not dis ...[truncated 1312 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Convert the returned gas price to Gwei and reject values above the configured maximum. - Require explicit approval when manual gas approval is configured. - Configure and enforce the expected chain ID rather than trusting the RPC response. - Add a provider hostname allowlist or require a trusted local node for high-value operation. - Simulate transactions before signing when simulation is enabled. - Implement real multisignature handling above the configured threshold or reject such transactions. - Wait for and verify the configured number of confirmations before reporting final success. - Use transaction fee bounds covering both legacy and EIP-1559 fee fields. - Add RPC timeouts and validate the nonce against local pending-transaction state. - Ensure the user approves a canonical summary containing recipient, value, chain ID, nonce, gas limit, and maximum total fee. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:168
Finding
Documented Security Requirements and Transaction API Do Not Match the Implementation<![CDATA[ ## Vulnerability Details **File Location**: `README.md:168-188`, compared with `ultra_secure_wallet_v13_MAXIMUM_SECURITY.py:705-710` and `1808-1809` **Vulnerability Type**: Security-sensitive documentation and interface mismatch **Risk Level**: Medium ### Vulnerable Code and Documentation The README documents the following call: ```python tx_result = api.send_transaction( wallet_id="my_first_wallet", to_address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", amount_eth=0.01, totp_code="123456" # From authenticator app ) ``` The implementation exposes different argument names: ```python def send_transaction(self, wallet_id: str, to_address: str, amount: float, mfa_code: str) -> Dict: ``` The README also states: ```markdown ### Password Requirements - Minimum 20 characters - Must contain uppercase, lowercase, digits, and special characters - Minimum entropy: 80 bits ``` The implementation requires: ```python MIN_PASSWORD_LENGTH: Final[int] = 64 RECOMMENDED_PASSWORD_LENGTH: Final[int] = 128 MIN_PASSWORD_ENTROPY_BITS: Final[int] = 256 ``` ### Technical Analysis The documented transaction example raises a `TypeError` because `amount_eth` and `totp_code` are not accepted keyword parameters. The password policy documented to users also differs materially from the enforced policy. These discrepancies affect a security-sensitive API. Integrators following the documentation cannot perform transactions and may modify the implementation, weaken validation, or create unreviewed wrappers to make the examples work. The documentation also describes backup codes as one-time recovery codes, but the reviewed transaction authentication path only verifies TOTP codes; no backup-code verification or invalidation path was found. ### Attack Path No direct remote exploit is established. A realistic operational failure path is: 1. An integrator copies the documented transaction example. 2. The call fails because the keyword argu ...[truncated 877 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Update all README and Skill examples to use the actual `amount` and `mfa_code` parameters, or rename the implementation parameters consistently. - Align the documented password policy with the implementation. - Clarify whether backup codes are implemented; remove the claim until secure one-time verification and invalidation exist. - Add executable documentation tests that run every example against the public API. - Define a stable, versioned API contract and test keyword-argument compatibility. - Avoid advising users to modify security constants directly. Expose validated configuration with documented safe ranges instead. - Reconcile claims across `README.md`, `SKILL.md`, configuration constants, runtime messages, and actual enforcement. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Known Vulnerable Dependency: pillow==10.0.0 — 16 advisory(ies): CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2024-28219 (Pillow buffer overflow vulnerability); CVE-2026-55379 (Pillow `BdfFontFile`: `Image.new()` called without `_decompression_bomb_check()`) +13 more

Critical
Category
Supply Chain
Confidence
98% confidence
Finding
The requirements file pins Pillow 10.0.0, and the supplied advisories include severe issues such as possible arbitrary code execution and memory-safety problems. Since this skill also includes QR-code generation and image handling, Pillow is likely reachable in normal operation, increasing the chance that malicious image input could lead to denial of service, memory corruption, or code execution depending on the vulnerable code path.

Known Vulnerable Dependency: web3==6.0.0 — 2 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)

High
Category
Supply Chain
Confidence
97% confidence
Finding
The requirements file pins web3 to version 6.0.0, and the provided advisory indicates this version is affected by an SSRF issue in CCIP Read / OffchainLookup URL handling. In an AI wallet payment system, blockchain interactions are core functionality, so a vulnerable web3 client could let attacker-controlled on-chain responses trigger server-side requests to unintended internal or external endpoints.

Known Vulnerable Dependency: cryptography==41.0.0 — 16 advisory(ies): CVE-2023-50782 (Python Cryptography package vulnerable to Bleichenbacher timing oracle attack); GHSA-537c-gmf6-5ccf (Vulnerable OpenSSL included in cryptography wheels); CVE-2024-26130 (cryptography NULL pointer dereference with pkcs12.serialize_key_and_certificates) +13 more

High
Category
Supply Chain
Confidence
94% confidence
Finding
The file pins cryptography to 41.0.0 despite multiple listed advisories affecting that version, including issues involving timing side channels and vulnerable bundled OpenSSL wheels. Because this project appears to handle wallet security, encryption, and authentication, weaknesses in a foundational cryptographic library can directly undermine confidentiality, integrity, or key-handling safety.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The module-level banner and guarantee text make sweeping security claims such as preventing every attack, wiping every secret, and implementing controls that are not actually present in the code. In a crypto wallet, these false assurances are dangerous because operators may trust the system with real funds and relax compensating controls based on inaccurate security claims.

Self-Modification

High
Category
Rogue Agent
Content
✓ Junk code insertion
✓ Opaque predicates
✓ Virtual machine obfuscation
✓ Self-modifying code
✓ Polymorphic code
✓ Metamorphic code
✓ White-box cryptography
Confidence
90% confidence
Finding
The file advertises self-modifying, polymorphic, and metamorphic code in its security claims. Even though the behavior is not implemented here, such claims are a red flag in an agent skill because they normalize techniques associated with evasion, hinder review, and suggest deceptive documentation about how the code behaves.

Missing User Warnings

High
Confidence
96% confidence
Finding
The transaction path signs and broadcasts an irreversible blockchain transfer immediately after API invocation without a separate explicit confirmation step showing recipient, amount, chain, and fees. In an agent-integrated payment skill, prompt injection, automation mistakes, or parameter confusion can therefore trigger unrecoverable fund loss.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The guide markets the system as 'secure' for AI-managed wallet and transaction use, but later discloses that it is experimental, unaudited, may contain vulnerabilities, and is suitable only for small amounts. This contradiction can cause operators to overtrust the skill with real funds, increasing the chance of financial loss from unsafe deployment.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**Ubuntu/Debian:**
```bash
sudo apt-get update
sudo apt-get install -y python3-dev libsqlcipher-dev build-essential libssl-dev
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**Ubuntu/Debian:**
```bash
sudo apt-get update
sudo apt-get install -y python3-dev libsqlcipher-dev build-essential libssl-dev
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**Ubuntu/Debian:**
```bash
sudo apt-get update
sudo apt-get install -y python3-dev libsqlcipher-dev build-essential libssl-dev
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**Ubuntu/Debian:**
```bash
sudo apt-get update
sudo apt-get install -y python3-dev libsqlcipher-dev build-essential libssl-dev
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**Ubuntu/Debian:**
```bash
sudo apt-get update
sudo apt-get install -y python3-dev libsqlcipher-dev build-essential libssl-dev
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Intent-Code Divergence

Medium
Confidence
81% confidence
Finding
The 'Implemented Security Features' list explicitly states 'Memory wiping' as a provided capability. Elsewhere, the guide warns that many claimed features are not implemented, which undermines confidence in categorical implementation claims and creates an intent/documentation mismatch unless the code clearly performs secure memory erasure. In this file, that claim is presented as implemented fact rather than aspirational or conditional behavior.

Known Vulnerable Dependency: python-dotenv==1.0.0 — 2 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)

Medium
Category
Supply Chain
Confidence
88% confidence
Finding
The file pins python-dotenv to 1.0.0, which the provided advisory states is vulnerable to symlink-following behavior in set_key that can enable arbitrary file overwrite in certain usage patterns. This is less universally exploitable than the other findings because it depends on the application calling the affected functionality on attacker-influenced paths, but in deployment or tooling contexts it can still lead to configuration corruption or overwrite of sensitive files.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The HSM interface claims HSM-backed key operations, but the implementation silently falls back to software-generated ephemeral keys and software encryption. This undermines the trust boundary around key custody and can cause users to believe hardware-backed protections exist when keys are actually handled in normal process memory.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The database component promises a write-once audit log, but the audit log is just a standard mutable SQLite table with no immutability or tamper-evidence enforcement. In a wallet system, mutable audit trails weaken incident response and allow post-incident deletion or alteration of evidence by anyone with DB write access.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The wallet manager states that private keys are never cached, yet plaintext private keys are created in process memory during wallet creation and transaction signing. Even if briefly held, this contradicts the guarantee and increases exposure to memory disclosure, crash dumps, debugging, or malicious local inspection.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The API claims HSM integration, perfect forward secrecy, anomaly detection, and hundreds of other protections that are not implemented in class behavior. This is especially dangerous in a payment wallet because downstream users may deploy it into production with unjustified confidence, exposing funds to avoidable compromise.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Check system security
        if hasattr(os, 'geteuid') and os.geteuid() == 0:
            raise SecurityException("NEVER run as root!")
        
        # Check for swap encryption (Linux)
        if platform.system() == 'Linux' and MaxSecurityConfig.DISABLE_SWAP:
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
Wallet creation returns the MFA secret and TOTP provisioning URI directly to the caller, and anyone who captures that response can enroll a second-factor generator and bypass MFA. In an agent or API setting, responses may be logged, forwarded, cached, or exposed to other tools, making this more dangerous than a local interactive setup flow.

Static analysis

No suspicious patterns detected.