T03 · Remote Payload Retrieval and Execution
- Location
x402_client.py:150- Finding
Unverified Remote Skill Packages Are Downloaded and Installed
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is purpose-aligned with blockchain-based skill payments and trust checks, but it handles wallet keys, signs transactions, and installs remote skill packages with insufficient safeguards.
Review this carefully before installing. Use only a dedicated low-value wallet, verify every RPC and contract address, avoid non-Arc CCTP flows until they are fully implemented, and do not trust downloaded skill packages unless their publisher and exact bytes are independently verified.
x402_client.py:150Unverified Remote Skill Packages Are Downloaded and Installed
x402_client.py:69Remote Server Can Override the Payment Amount After User Confirmation
cctp_client.py:121Incomplete CCTP Flow Can Burn or Strand Funds While Reporting Success
arc_contract.py:119Reverted Blockchain Transactions Are Reported as Successful
requirements.txt:1Dependencies Are Mutable and Not Integrity-Pinned
The code signs and submits blockchain approval and authorizeUsage transactions automatically based on payment instructions from the server's 402 response. This can cause unintended token approvals and spending without an explicit consent checkpoint, and in this context the server controls key payment parameters such as amount and memo, making the automation materially risky.
The cross-chain flow automatically initiates a burn/payment process and then finalizes authorization on Arc without requiring the user to confirm the multi-step transfer. Because cross-chain operations are harder to reverse and rely on attestations and external infrastructure, automatic execution increases the risk of accidental fund loss or abuse if the remote service or configuration is malicious or compromised.
The client automatically downloads and extracts a ZIP returned by a remote server immediately after payment, with no confirmation or inspection step. In a skill-installation context this is especially dangerous because a malicious or compromised server can deliver an archive containing harmful files, path traversal entries, or executable content that the user did not knowingly approve.
The README instructs users to perform value-bearing blockchain actions such as paying, staking USDC, voting on claims, and withdrawing earnings, but it does not warn that these actions can be irreversible, may transfer real funds, and may expose users to wallet or network-selection mistakes. In a security-themed skill, users may infer the workflow is trustworthy and low-risk, which increases the chance of unsafe financial actions without informed consent.
The README tells users to set a PRIVATE_KEY environment variable for transaction signing but provides no guidance on secure handling, storage, or scoping of that credential. This is dangerous because private keys grant direct control over wallet funds, and exposing them through shell history, process environments, logs, shared machines, or misconfigured deployment environments can lead to complete wallet compromise.
The documentation instructs users to provide a wallet private key, which is an extremely sensitive credential, but gives no guidance on secure handling, storage, or use of safer alternatives. In a skill that performs blockchain payments and contract calls, this omission materially increases the chance of key exposure, wallet compromise, and unauthorized fund movement.
The use command is described as automatically paying a fee and downloading a skill package, while also selecting a payment path based on wallet balances, but it does not warn users that it will spend funds and fetch external content. Because the downloaded package is a skill artifact and the trust model explicitly labels skills as 'Safe to use,' this can encourage users to treat an automated paid download as low risk when it can still expose them to malicious or unreviewed content.
The class docstring says this is an interface to the SkillSecurityRegistry contract on Arc, but the bundled fallback ABI only defines getSkillInfo while the class also implements getClaimInfo, pendingEarnings, submitClaim, voteOnClaim, and claimEarnings. This creates a direct documentation-to-code inconsistency about what interface is actually supported and can mislead callers about available contract operations.
The code reads a sensitive credential from the PRIVATE_KEY environment variable, but there is no confirmation prompt, visible logging, or comment/docstring warning users that wallet credentials will be accessed for signing transactions. For a code file, credential access should include some disclosure unless clearly warned elsewhere in accompanying markdown, which is not present in this file.
The module signs and broadcasts a blockchain transaction immediately once submit_claim is called, with no explicit consent, dry-run, or transaction review step. In an agent skill context, this is dangerous because any upstream prompt injection, misuse, or accidental invocation can cause irreversible on-chain actions and consume funds from the loaded private key.
This method signs and sends a vote transaction without any explicit approval or review by the user. In a skill or agent environment, silent transaction submission can be abused to manipulate governance actions or simply drain gas through repeated calls, and blockchain transactions are typically irreversible once broadcast.
The earnings-claim path broadcasts a signed transaction immediately, again with no explicit confirmation, despite moving value or affecting fund flows. In the context of an agent skill that may run automatically, this creates a meaningful risk of unauthorized asset movement, gas expenditure, or mistakes involving the destination chain domain.
The function advertises waiting for a CCTP attestation but instead returns hardcoded placeholder message and attestation bytes with success=true almost immediately. In a cross-chain transfer client, this can cause downstream code to submit invalid finalization transactions, misreport bridge completion, and potentially trigger loss of funds, stuck funds, or unsafe automation decisions.
The receive_message method signs and broadcasts a blockchain transaction that completes the cross-chain transfer, but unlike bond_skill it provides no print/log message, confirmation prompt, or explanatory comment warning the user that an on-chain state-changing action is being sent. For a code file, this is a safety-critical operation with potential cost and irreversible effects, and there is no visible disclosure in this method.
The file is presented as a 'USDC Security Skill' checker/router, but it also initiates paid skill acquisition, bonding/staking, reporting, voting, and earnings withdrawal. This mismatch is dangerous because users may grant trust or run the tool expecting passive security assessment when it actually triggers financially sensitive actions.
Labeling a bonded, unflagged skill as 'Safe to use' makes an unjustified security claim based only on bonding/flag state, which is not equivalent to a real security review. In this context, that output can materially mislead users into executing or paying for potentially unsafe skills, making the issue more dangerous than a mere wording problem.
The code submits an on-chain vote immediately after only an eligibility check, without a dedicated confirmation prompt summarizing the claim ID, vote direction, wallet, and transaction consequences. In a wallet-connected CLI, this increases the risk of accidental governance actions or social-engineered invocation that causes irreversible or reputation-impacting votes.
The trigger "check" is vague and can match many benign requests, making unintended invocation plausible. Because this skill is positioned as security infrastructure and may query blockchain, registry, or payment-related systems, ambiguous activation can expose users to incorrect trust decisions, unnecessary external calls, or unsafe follow-on actions.
The command trigger "use" is extremely generic and likely to collide with ordinary user language, increasing the chance that the skill is invoked unintentionally. In a security-sensitive skill that can perform trust, bonding, reporting, and claims-related actions, accidental activation could lead to confusing, misleading, or risky workflows being initiated without clear user intent.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
'X-Payment-Proof': json.dumps(payment_proof)
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
content_type = response.headers.get('Content-Type', '')
The comment claims ZIP handling is only simulated, but the code actually writes a server-supplied archive to disk and extracts it. This mismatch is dangerous because it can mislead reviewers and users into underestimating the risk of processing untrusted archive content, including path traversal or malicious payload installation.
The dependency web3>=6.0.0 is not pinned to an exact version, which makes builds non-reproducible and can cause different environments to install different releases over time. In a security-sensitive package like web3, this increases the chance of unintentionally pulling in a vulnerable or behavior-changing version.
web3>=6.0.0
requests>=2.31.0
python-dotenv>=1.0.0
web3 has known advisories, and because the manifest does not pin a specific version, it is impossible to verify from this file whether the installed release is affected. This is more concerning in skill code that may interact with blockchain endpoints or off-chain resolution mechanisms, where an affected web3 version could expose the environment to issues such as SSRF.
The dependency requests>=2.31.0 is unpinned, so future installs may resolve to different versions with different security properties. Because requests is commonly used for outbound HTTP and has a history of security advisories, leaving it unpinned increases supply-chain and patch-verification risk.
web3>=6.0.0
requests>=2.31.0
python-dotenv>=1.0.0
requests has multiple known advisories, but the unpinned requirement prevents determining whether the deployed version is safe. Since requests directly handles HTTP interactions, an affected version could expose credentials, alter TLS verification behavior, or mishandle attacker-controlled URLs depending on how the skill uses it.
No suspicious patterns detected.