Back to skill

Security audit

Vincent - A secure wallet for your agent

Security checks for vulnerabilities and agentic risk

Overview

This wallet skill is coherent and not deceptive, but it gives agents broad financial authority with unsafe defaults and weak credential-handling guidance.

Install only if you are comfortable giving an agent transaction-capable wallet access. Claim the wallet before funding it, configure strict policies first, require approval for meaningful transactions, avoid raw signing or arbitrary calldata unless you fully understand the payload, and do not store API keys in a project directory or any location that could be committed, synced, logged, or shared.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:216
Finding
Wallet Bearer Credentials Are Persisted Without Mandatory Filesystem Protections<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 40 and 216-217 **Vulnerability Type**: Plaintext sensitive credential storage **Risk Level**: High ### Vulnerable Code ```markdown All API requests require a Bearer token (the API key returned when creating a wallet). If you're an openclaw instance, store and retrieve it from `~/.openclaw/credentials/agentwallet/<API_KEY_ID>.json`. Otherwise, you can store it in your current working directory at `agentwallet/<API_KEY_ID>.json`. ``` ```markdown - Always store the API key from wallet creation. If you're an openclaw instance, store it in `~/.openclaw/credentials/agentwallet/<API_KEY_ID>.json`. Otherwise, you can store it in your current working directory at `agentwallet/<API_KEY_ID>.json`. - Always search for the API keys in the credentials folder before using the API. If you're an openclaw instance, search for the API key in `~/.openclaw/credentials/agentwallet/<API_KEY_ID>.json`. Otherwise, you can search for the API key in your current working directory at `agentwallet/<API_KEY_ID>.json`. ``` ### Technical Analysis The API key is a bearer credential authorizing financially consequential wallet operations. The Skill directs the agent to persist this credential in a JSON file but does not require restrictive directory or file permissions, encryption at rest, use of an operating-system credential manager, log redaction, or protection against source-control inclusion. The fallback location under the current working directory is especially unsafe because it may be inside a repository, shared workspace, synchronized directory, build context, or backup set. A plaintext key could consequently be exposed through an accidental commit, artifact upload, permissive file mode, workspace sharing, or access by another local process. Searching the dedicated `agentwallet` directory is reasonably connected to credential retrieval and is not evidence of indiscriminate credential harvesting. The security ...[truncated 1165 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store the API key in an operating-system credential manager or platform-provided secret store rather than a project directory. 2. If file storage is unavoidable, require the credential directory to use mode `0700` and each credential file to use mode `0600`. 3. Prohibit credential storage under the current working directory or any source-controlled project. 4. Add `agentwallet/` and equivalent credential paths to source-control ignore rules. 5. Use atomic file creation with restrictive permissions rather than creating a permissive file and changing its mode afterward. 6. Never print the bearer key in logs, command output, error messages, telemetry, or conversational responses. 7. Document key revocation and rotation procedures and rotate a key immediately after suspected disclosure. 8. Where supported, issue narrowly scoped and short-lived credentials instead of long-lived bearer keys. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:176
Finding
New Wallets Permit Unrestricted Financial Operations Until Policies Are Configured<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 176-182 **Vulnerability Type**: Fail-open authorization and excessive default privilege **Risk Level**: High ### Vulnerable Code ```markdown | Policy | What it does | | --------------------------- | ------------------------------------------------------------------- | | **Address allowlist** | Only allow transfers/calls to specific addresses | | **Token allowlist** | Only allow transfers of specific ERC-20 tokens | | **Function allowlist** | Only allow calling specific contract functions (by 4-byte selector) | | **Spending limit (per tx)** | Max USD value per transaction | | **Spending limit (daily)** | Max USD value per rolling 24 hours | | **Spending limit (weekly)** | Max USD value per rolling 7 days | | **Require approval** | Every transaction needs human approval via Telegram | | **Approval threshold** | Transactions above a USD amount need human approval | If no policies are set, all actions are allowed by default. Once the owner claims the wallet and adds policies, the agent operates within those boundaries. ``` ### Technical Analysis The authorization model is fail-open: a newly created wallet is usable without an address allowlist, token allowlist, function allowlist, spending limit, or human approval requirement. Wallet creation also returns an operative bearer key before the owner necessarily follows the claim URL and configures restrictions. This exceeds the minimum privilege needed to establish a wallet. Creation and ownership-claim operations do not require immediate unrestricted permission to transfer assets, swap tokens, place bets, or execute arbitrary contract calldata. Because blockchai ...[truncated 1656 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Change the default authorization state to deny all financially consequential operations. 2. Permit wallet creation and address retrieval before claim, but block signing and transaction execution until ownership is claimed. 3. Require explicit policy configuration before the wallet can receive an active transaction-capable API key. 4. Apply conservative default controls, including: - A low per-transaction spending limit. - Low daily and weekly limits. - Mandatory human approval. - Empty address, token, and function allowlists. 5. Require a separate, explicit owner action to enable arbitrary contract calls and raw signing. 6. Warn the user not to fund the wallet until claim and policy configuration are complete. 7. Display the effective policy state before each financially consequential operation. 8. Add an activation workflow that verifies ownership and records affirmative consent to the configured limits. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:298
Finding
Balance Retrieval Unexpectedly Deploys a Wallet and Grants Token Approval<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 298-305 **Vulnerability Type**: State-changing side effects in a read operation **Risk Level**: Medium ### Vulnerable Code ```markdown ### Get Balance ```bash curl -X GET "https://heyvincent.ai/api/skills/polymarket/balance" \ -H "Authorization: Bearer <API_KEY>" ``` Returns: - `walletAddress` -- the Safe address (deployed on first call if needed) - `collateral.balance` -- USDC.e balance available for trading - `collateral.allowance` -- approved amount for Polymarket contracts **Note:** The first balance call triggers Safe deployment and collateral approval (gasless via relayer). This may take 30-60 seconds. ``` ### Technical Analysis The nominally read-only `GET /balance` operation performs two state-changing actions: Safe deployment and collateral approval. This violates the expected safety and idempotency semantics of an HTTP `GET` request and combines account inspection with authorization of a token spender. Automated agents, monitoring systems, browsers, caches, or retry mechanisms may invoke or repeat a balance request under the assumption that it cannot alter blockchain state. Although the side effect is disclosed in the documentation, disclosure does not provide separate, affirmative consent to the spender, allowance amount, or deployment action. Token approval creates authority that can remain in place after the balance request. The exact spender and allowance scope are not shown in the audited documentation, so the report does not assume an unlimited allowance; however, any nonzero approval expands the trusted execution surface. ### Attack Path 1. A user or agent requests the Polymarket wallet balance, expecting a read-only operation. 2. The service deploys the Safe on the first request. 3. The service also submits a collateral approval for Polymarket contracts. 4. The approval remains active after the balance response. 5. If an approved spender or an associated integ ...[truncated 656 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make the balance endpoint strictly read-only and free of blockchain state changes. 2. Move Safe deployment to a dedicated authenticated `POST` endpoint with explicit user confirmation. 3. Move collateral approval to a separate authenticated `POST` endpoint. 4. Before approval, display the exact token, spender address, chain, allowance amount, expiration mechanism, and associated risks. 5. Prefer exact or minimal allowances over broad approvals. 6. Require renewed consent when an allowance must be increased. 7. Provide an endpoint and documented procedure for inspecting and revoking existing allowances. 8. Ensure retries and monitoring requests cannot repeat deployment or approval actions. 9. Record deployment and approval as distinct auditable events rather than representing them as part of balance retrieval. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (8)

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The skill instructs the agent to store bearer API keys on the local filesystem and later retrieve them for wallet operations. Because these keys authorize transfers, swaps, arbitrary contract calls, raw signing, and betting, local credential persistence materially expands the skill from transaction execution into secret handling and creates a theft/reuse risk if the host, workspace, logs, or other tools are compromised.

External Transmission

Medium
Category
Data Exfiltration
Content
Create a new smart account wallet for your agent. This generates a private key server-side (you never see it), creates a ZeroDev smart account, and returns an API key for the agent plus a claim URL for the wallet owner.

```bash
curl -X POST "https://heyvincent.ai/api/secrets" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "EVM_WALLET",
Confidence
60% 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
97% confidence
Finding
The arbitrary transaction feature allows sending custom calldata to any smart contract, which can approve token spending, transfer assets, interact with malicious contracts, or trigger irreversible state changes. Documenting this capability without a strong warning and without emphasizing selector/address restrictions is dangerous because users may treat it like a normal transfer rather than a full-power contract execution primitive.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that if no policies are set, all wallet actions are allowed by default, yet it does not foreground this as a critical risk before enabling transfers, swaps, contract calls, or betting. In the context of an agent wallet, permissive defaults mean a newly created or unclaimed wallet can be used for broad financial actions without clear user understanding of the exposure.

External Transmission

Medium
Category
Data Exfiltration
Content
3. The agent calls the re-link endpoint to exchange the token for a new API key

```bash
curl -X POST "https://heyvincent.ai/api/secrets/relink" \
  -H "Content-Type: application/json" \
  -d '{
    "relinkToken": "<TOKEN_FROM_USER>",
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
Telling the agent to search credential directories for API keys is an unnecessary credential-discovery behavior that can lead to overbroad access to unrelated wallet secrets present on the machine. In this skill, any discovered key can unlock high-risk financial actions, so this effectively encourages lateral secret access beyond the user's immediate request.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
Raw signing is one of the highest-risk wallet capabilities because signatures over untrusted payloads can authorize asset transfers, off-chain orders, permits, login sessions, or transaction broadcasts that bypass smart-account policy controls. The skill presents raw ECDSA/Ed25519 signing as an advanced feature but lacks a strong warning that the agent must never sign opaque or user-supplied payloads without trusted decoding and explicit approval.

External Transmission

Medium
Category
Data Exfiltration
Content
### Create a Polymarket Wallet

```bash
curl -X POST "https://heyvincent.ai/api/secrets" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "POLYMARKET_WALLET",
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.