Back to skill

Security audit

Zora NFT Pro

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it advertises, but it asks for a raw wallet private key and can sign and broadcast blockchain transactions without a review or confirmation step.

Review this carefully before installing. Do not use a primary wallet or funded wallet private key with this skill; if you test it, use a dedicated low-value deployment wallet and require a manual transaction review path. The package should add explicit on-chain warnings, transaction preview and confirmation, chain and contract validation, safer signer handling, and pinned dependencies before routine use.

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
scriptsmain.py:7
Finding
Unsafe Construction and Broadcasting of Wallet-Signed Transactions## Vulnerability Details **File Location**: `scriptsmain.py`, lines 7-9 and 27-40 **Vulnerability Type**: Unsafe blockchain transaction signing and broadcasting **Risk Level**: High ### Vulnerable Code ```python PRIVATE_KEY = os.getenv("PRIVATE_KEY") ACCOUNT = w3.eth.account.from_key(PRIVATE_KEY) ``` ```python def deploy_to_zora(image_path, name, symbol): """Deploys a basic ERC721 to Zora Network.""" # Simplified Zora Minting Logic # 1. Upload image_path to IPFS (using a service like Pinata or Zora API) ipfs_link = "ipfs://..." # 2. Build Transaction for Zora 721 Factory # (Simplified for example) tx = { 'from': ACCOUNT.address, 'nonce': w3.eth.get_transaction_count(ACCOUNT.address), 'gas': 2000000, 'maxFeePerGas': w3.to_wei('2', 'gwei'), 'maxPriorityFeePerGas': w3.to_wei('1', 'gwei'), 'data': '0x...' # Zora Contract Creation Bytecode } signed_tx = w3.eth.account.sign_transaction(tx, PRIVATE_KEY) tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction) return w3.to_hex(tx_hash) ``` ### Technical Analysis The module reads a wallet private key and derives the signing account during import. The deployment function then signs and broadcasts a transaction without validating critical transaction properties. The transaction has no verified Zora factory contract address, explicit chain ID, valid audited deployment bytecode, gas estimation, or confirmation step. Its `data` field contains the placeholder value `0x...`, which is not valid contract creation bytecode. The hardcoded gas and fee limits are also not checked against current network conditions. Because no `to` address is supplied, the transaction is treated as contract creation rather than a call to a documented Zora factory. As currently written, the placeholder data will ordinarily cause transaction construction or submission to fail. If the ...[truncated 1818 chars]
Remediation
## Remediation Suggestions 1. Do not initialize the signing account at module import. Load the key only inside a narrowly scoped signing component when a transaction is ready for authorization. 2. Verify that `ZORA_RPC_URL` reports the expected Zora chain ID before constructing or signing any transaction. 3. Use the official, audited Zora factory contract address and ABI rather than raw placeholder deployment bytecode. 4. Add an explicit `chainId` and validate the destination address, calldata, value, nonce, fee limits, and expected contract operation. 5. Generate calldata through the contract ABI and ensure the collection name, symbol, and metadata URI are encoded as expected. 6. Estimate gas through the RPC and apply a bounded safety margin instead of using a fixed gas limit. 7. Simulate the transaction and reject reverts or unexpected state changes before signing. 8. Present the destination, chain, maximum fee, value, and decoded operation for explicit operator confirmation. 9. Use a dedicated low-value deployment wallet or external signer rather than a general-purpose private key. 10. Fail closed when required environment variables are absent, malformed, or inconsistent.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Third-Party Dependencies Create Supply-Chain Risk## Vulnerability Details **File Location**: `requirements.txt`, lines 1-3 **Vulnerability Type**: Unpinned and non-reproducible dependencies **Risk Level**: Medium ### Vulnerable Code ```text google-generativeai web3 requests ``` ### Technical Analysis Every dependency is declared without a version constraint or integrity hash. Consequently, separate installations can resolve to different package versions, including newly released versions that were not reviewed with the project. This weakens build reproducibility and increases exposure to compromised upstream releases, malicious dependency updates, or breaking behavioral changes. The project also declares `requests`, although no use of that package was identified in the reviewed Python file. Unnecessary dependencies expand the available supply-chain attack surface. The audit did not identify a confirmed malicious package or an unsafe custom package source. The issue is the absence of controls that ensure installations receive the exact reviewed artifacts. ### Attack Path 1. A developer, deployment system, or user executes `pip install -r requirements.txt`. 2. The package resolver queries the configured Python package index for currently compatible releases. 3. Because no versions or hashes are specified, it may install releases that differ from those originally tested or audited. 4. If an upstream account or release is compromised, malicious package code can execute during installation or when the dependency is imported. 5. Such code would run with the privileges of the installation process or application process. ### Impact Assessment A compromised dependency could access the same environment and process privileges as the skill, potentially including `GEMINI_API_KEY`, `PRIVATE_KEY`, the filesystem, and network connectivity. This means the theoretical impact includes credential theft, unauthorized wallet operations, arbitrary code execution, and modification o ...[truncated 180 chars]
Remediation
## Remediation Suggestions 1. Pin every direct dependency to a reviewed version. 2. Generate a lockfile containing resolved transitive dependencies. 3. Require package hashes, for example through a hash-locked requirements file and `pip install --require-hashes`. 4. Remove `requests` unless the implementation genuinely requires it. 5. Run dependency vulnerability and license scanning in continuous integration. 6. Review updates before regenerating the lockfile rather than accepting unconstrained releases automatically. 7. Install dependencies from a trusted, explicitly configured package index. 8. Execute the application in an isolated environment with minimal filesystem, network, and credential access.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares access to sensitive environment-backed capabilities implicitly by requiring secrets like GEMINI_API_KEY and PRIVATE_KEY, but it does not define any explicit tool scope or permission boundary. In a skill that can generate assets and perform blockchain deployment, missing scope declarations increases the chance of overbroad secret access or unintended use of privileged runtime capabilities.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill advertises immediate NFT deployment to Zora but does not clearly warn users that blockchain deployment and minting are irreversible, may incur fees, and publish data permanently. In this context, omission of those warnings is dangerous because users may trigger real on-chain actions without understanding financial cost, permanence, or public exposure.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill requests a wallet PRIVATE_KEY for Zora deployment without any safety guidance on handling sensitive credentials, which normalizes exposing the most privileged wallet secret to the skill runtime. In a blockchain deployment context, compromise or misuse of that key could lead to theft of funds, unauthorized transactions, and full loss of control over the associated wallet.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill loads a raw PRIVATE_KEY from the environment and immediately derives an account used for signing blockchain transactions, but nowhere in the user-facing flow does it disclose that the skill can spend funds or create on-chain state. In an agent setting, this is dangerous because a benign-seeming content-generation request can silently trigger signing authority tied to a real wallet, enabling unintended spending or asset deployment.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The function unconditionally proceeds from prompt input to transaction broadcast via send_raw_transaction, with no approval step, transaction preview, or warning that deployment to Zora is an irreversible on-chain action. In this skill context, that is especially risky because the tool is framed as NFT generation, so users may not realize it will actually deploy contracts and consume wallet funds automatically.

Unpinned Dependencies

Low
Category
Supply Chain
Content
google-generativeai
web3
requests
Confidence
98% confidence
Finding
The dependency `google-generativeai` is unpinned, so installs may resolve to different versions over time, including releases with breaking changes or newly introduced vulnerabilities. This weakens build reproducibility and increases supply-chain risk, especially for an automation skill that interacts with external services.

Unpinned Dependencies

Low
Category
Supply Chain
Content
google-generativeai
web3
requests
Confidence
99% confidence
Finding
The dependency `web3` is unpinned, which creates supply-chain and reproducibility risk because future installs may pull in vulnerable or incompatible versions. In this skill's context, `web3` is used for blockchain interaction, so a vulnerable or changed release could affect transaction handling or expose network-facing attack surface.

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
95% confidence
Finding
`web3` has known advisories, and because the manifest does not pin a version, there is no way to verify whether installation will select a safe release. This is more concerning here because the skill deploys to the Zora network, so `web3` is central to transaction and RPC handling; if an affected version is installed, issues such as SSRF-related behavior could become reachable through attacker-influenced blockchain responses or endpoints.

Unpinned Dependencies

Low
Category
Supply Chain
Content
google-generativeai
web3
requests
Confidence
99% confidence
Finding
The dependency `requests` is unpinned, allowing installation of arbitrary future versions or outdated vulnerable versions depending on the environment. Because this skill likely makes external HTTP requests for generation or deployment workflows, weaknesses in `requests` could directly affect confidentiality or request integrity.

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
97% confidence
Finding
`requests` has multiple known advisories, but the lack of version pinning makes it impossible to determine whether the installed package is patched. In this skill's context, network communication is likely required for image generation and blockchain-related APIs, so an affected `requests` version could expose credentials, mishandle TLS/session verification, or leak data during outbound requests.

Static analysis

No suspicious patterns detected.