Back to skill

Security audit

Vincent - Agent Wallet

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed wallet integration, but it gives an agent broad financial authority with fail-open policies and weak credential-handling guidance.

Review this skill carefully before installing. Only use it if you trust the hosted wallet service and are comfortable giving an agent wallet authority. Claim the wallet immediately, configure approval requirements, spending limits, and allowlists before funding it, store API keys in a real secret store rather than a project directory, and treat API keys or re-link tokens like wallet credentials. Be aware that the Polymarket balance call can deploy a Safe and approve collateral.

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:40
Finding
Wallet Bearer Tokens Are Persisted Without Mandatory Storage Protections<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:40-44` and `SKILL.md:216-217` **Vulnerability Type**: Plaintext storage of financially sensitive bearer credentials **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`. \`\`\` Authorization: Bearer <API_KEY> \`\`\` ``` The storage and lookup requirements are repeated later: ```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 Skill requires persistent storage of a bearer token that authorizes financially sensitive wallet operations. However, it does not require encryption, an operating-system secret manager, restrictive directory and file permissions, repository exclusions, or credential redaction. The fallback location under the current working directory is particularly unsafe. Such files may be committed to source control, included in build artifacts or backups, exposed to other workspace users, or read by unrelated tools operating in the same project directory. Searching the dedicated credential directory is functionally related to the Skill and does not, by itself, exceed the minimum privilege required to retrieve this Skill's own token. The risk arises fr ...[truncated 1492 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store API keys in an operating-system credential manager or a dedicated secrets service rather than ordinary JSON files. 2. Remove the current-working-directory fallback because project folders are commonly synchronized, archived, or committed. 3. If filesystem storage is unavoidable: - Create the credential directory with mode `0700`. - Create credential files atomically with mode `0600`. - Reject symlinks and verify file ownership before reading. - Keep credentials outside repositories and shared workspaces. 4. Add the credential path to applicable source-control, backup, and artifact exclusion rules. 5. Never place bearer tokens in command output, logs, error reports, prompts, or shell history. 6. Provide token revocation and rotation procedures, including immediate rotation following suspected disclosure. 7. Store only the credential selected for the active wallet rather than broadly enumerating unrelated credential files. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:160
Finding
New Wallets Permit Financial Operations Before Restrictive Policies Are Configured<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:160-180` **Vulnerability Type**: Fail-open financial authorization and excessive default privilege **Risk Level**: High ### Vulnerable Code ```markdown ## Policies The wallet owner controls what the agent can do by setting policies via the claim URL. If a transaction violates a policy, the API will reject it or require human approval via Telegram. | 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: when no policy has been configured, the bearer token may perform all supported actions by default. Wallet creation returns the API key before the owner necessarily visits the claim URL and establishes restrictions. This creates an exposure window in which the agent credential has broader authority than is normally necessary. Policy ...[truncated 1584 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Change the initial wallet state from allow-all to deny-by-default. 2. Do not enable transaction or signing endpoints until the owner has claimed the wallet. 3. Install conservative baseline policies automatically, including: - Human approval for every transaction. - Low per-transaction and cumulative spending limits. - Empty or explicitly configured address, token, and function allowlists. - Raw signing disabled unless separately authorized. 4. Require an explicit owner confirmation before enabling arbitrary transaction calldata. 5. Make policy activation atomic with wallet enablement so there is no unprotected interval. 6. Clearly display the effective policy state to both the agent and owner before any transaction. 7. Consider short-lived, narrowly scoped credentials rather than one bearer token covering all wallet capabilities. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:326
Finding
Balance Retrieval Unexpectedly Deploys a Wallet and Grants Token Approval<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:326-331` **Vulnerability Type**: Hidden state-changing behavior in a read-oriented endpoint **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 documented `GET /balance` operation is not read-only. Its first invocation deploys a Safe and performs a collateral approval. This violates the normal safety and idempotence expectations associated with HTTP GET requests and makes a routine inspection operation produce on-chain state changes. The Skill does not identify the exact approval spender, approval amount, expiration behavior, or revocation procedure. Consequently, an agent or user requesting only balance information may unintentionally establish token-spending authority for external contracts. Although the approval is described as being for Polymarket contracts and is related to the wallet's intended trading functionality, coupling it to balance retrieval is not the minimum authority necessary to obtain a balance. ### Attack Path 1. An agent creates a Polymarket wallet. 2. The agent calls the documented GET balance endpoint to determine the wallet address or inspect funds. 3. The backend interprets the first balance request as authorization to deploy the Safe and approve collateral. 4. An on-chain allowance is established for the configured Polymarket contract or contracts without a separate transaction-specific confirmation. 5. If the approved contract, spender configuratio ...[truncated 683 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make the balance endpoint strictly read-only. 2. Move Safe deployment into a separate authenticated `POST` operation with explicit user confirmation. 3. Move collateral approval into another explicit `POST` operation performed only when trading is enabled. 4. Before approval, disclose: - The exact spender address. - The token contract. - The requested allowance. - The chain ID. - The reason and duration of the approval. 5. Prefer exact or bounded allowances over unlimited approvals. 6. Provide an endpoint and documented workflow to inspect and revoke existing allowances. 7. Require fresh approval when the spender address or integration configuration changes. 8. Avoid state changes through GET requests so crawlers, retries, previews, and balance checks cannot trigger financial authorization side effects. ]]>
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 (5)

Missing User Warnings

High
Confidence
97% confidence
Finding
The statement that all actions are allowed by default if no policies are set creates a dangerous default-permit model for a wallet-controlling agent. In context, this is especially risky because the same skill supports arbitrary transactions and raw signing, so a newly created or unclaimed wallet may be fully usable for sensitive operations before any user protections are configured.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This skill enables high-risk financial actions including transfers, swaps, arbitrary contract calls, raw signing, and betting, but the introductory guidance emphasizes convenience and safety of key handling more than the fact that real assets can be irreversibly spent. In an agent setting, that omission materially increases the chance of accidental fund movement or user misunderstanding, especially because the skill normalizes autonomous transaction execution.

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.

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
83% confidence
Finding
The re-link flow instructs the agent to accept a one-time token from the user and exchange it for a new API key on an unauthenticated endpoint, making possession of the token equivalent to wallet access. In an agent environment, such tokens are highly susceptible to prompt leakage, logging, transcript retention, or social engineering, so this workflow creates a meaningful credential-capture and account-takeover risk.

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.