Back to skill

Security audit

circle-wallet

Security checks for vulnerabilities and agentic risk

Overview

This is a real Circle wallet tool, but it needs review because it can move funds and stores sensitive wallet credentials with weak safeguards.

Review carefully before installing. Use sandbox/testnet first, avoid production credentials unless you trust the environment, do not pass secrets in commands that may be logged, restrict permissions on ~/.openclaw/circle-wallet/, and require manual review before any send operation. Rotate Circle credentials if they may already have been exposed through shell history, process logs, or an overly readable config file.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/config.ts:11
Finding

Wallet Credentials Stored in Plaintext Without Explicitly Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Location: src/config.ts:11-32
Vulnerability Type: Plaintext sensitive-data storage with insufficient permission enforcement
Risk Level: High

The configuration file stores the Circle API key and entity secret. These credentials are supplied to saveConfig() from src/cli.ts:75-80 and src/cli.ts:125-130.

ts
const CONFIG_DIR = path.join(process.env.HOME || '~', '.openclaw', 'circle-wallet');
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');

export function ensureConfigDir(): void {
  if (!fs.existsSync(CONFIG_DIR)) {
    fs.mkdirSync(CONFIG_DIR, { recursive: true });
  }
}

export function loadConfig(): WalletConfig {
  ensureConfigDir();

  if (!fs.existsSync(CONFIG_FILE)) {
    throw new Error('No configuration found. Run "circle-wallet setup" first.');
  }

  const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
  return config;
}

export function saveConfig(config: WalletConfig): void {
  ensureConfigDir();
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
}

The sensitive values written by these functions include:

ts
saveConfig({
  apiKey,
  entitySecret,
  env,
  defaultChain: env === 'sandbox' ? 'ARC-TESTNET' : 'BASE'
});

Technical Analysis

config.json contains both the Circle API key and the entity secret in plaintext. The code does not assign an explicit mode when creating the configuration directory or writing the credential file. Consequently, access control depends on the process umask and any pre-existing directory or file permissions.

The entity secret is used by the Circle SDK to protect developer-controlled wallet operations, while the API key authenticates API requests. Disclosure of both values can therefore expose financially sensitive wallet capabilities.

This behavior exceeds the minimum safe privilege model for credential storage: persistent storage is neces ...[truncated 1342 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create the credential directory with owner-only permissions:

    ts
    fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
    fs.chmodSync(CONFIG_DIR, 0o700);
    
  2. Create and update the configuration file with mode 0600:

    ts
    fs.writeFileSync(
      CONFIG_FILE,
      JSON.stringify(config, null, 2),
      { encoding: 'utf8', mode: 0o600 }
    );
    fs.chmodSync(CONFIG_FILE, 0o600);
    
  3. Use an atomic write through a private temporary file to avoid partial writes and permission inconsistencies.

  4. Check whether the path is a symbolic link before writing, and avoid following attacker-controlled links.

  5. Migrate existing installations by checking and repairing directory and file permissions.

  6. Prefer an operating-system keychain, credential vault, or dedicated secret manager instead of plaintext JSON.

  7. Document credential rotation procedures and advise users to rotate credentials if the file may previously have been readable by unintended principals.

T09 · Insecure Skill Coding Practices

Warning
Location
src/cli.ts:24
Finding

API Key and Entity Secret Accepted Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: src/cli.ts:24-31, 97-102
Vulnerability Type: Sensitive credentials exposed through process arguments and command history
Risk Level: Medium

The setup command requires the API key as a command-line option:

ts
program
  .command('setup')
  .description('Generate and configure Entity Secret')
  .requiredOption('--api-key <key>', 'Circle API key')
  .option('--env <environment>', 'Environment (sandbox or production)', 'sandbox')
  .action(async (options: { apiKey: string; env: string }) => {

The configure command requires both sensitive credentials as command-line options:

ts
program
  .command('configure')
  .description('Configure with existing credentials')
  .requiredOption('--api-key <key>', 'Circle API key')
  .requiredOption('--entity-secret <secret>', 'Entity secret')
  .option('--env <environment>', 'Environment (sandbox or production)', 'sandbox')
  .action(async (options: { apiKey: string; entitySecret: string; env: string }) => {

The documentation explicitly instructs users to provide literal secrets this way:

bash
circle-wallet setup --api-key your-api-key
circle-wallet configure --api-key your-key --entity-secret your-secret

Technical Analysis

Command-line arguments are not an appropriate transport for long-lived secrets. Depending on the operating system and execution environment, arguments may be exposed through process inspection, shell history, terminal recording, audit logs, agent tool traces, crash diagnostics, and command telemetry.

This is particularly significant for an agent-oriented Skill because invocations may be retained in orchestration logs beyond the lifetime of the process. The configure command places both factors required by the SDK—the API key and entity secret—into the same potentially recorded command.

Sending these credentials to the official ...[truncated 1536 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove secret-bearing command-line options as the preferred configuration method.
  2. Read secrets using a masked interactive prompt that does not echo input.
  3. Support standard input or a permission-restricted credential file for non-interactive agent execution.
  4. Integrate with an operating-system keychain or secret manager and accept a credential reference rather than the secret itself.
  5. If environment variables remain supported, clearly warn that some execution platforms log environment values and recommend runtime secret injection.
  6. Remove literal-secret command examples from SKILL.md.
  7. Add warnings that credentials previously supplied as arguments may remain in shell or agent history.
  8. Recommend rotating API keys and entity secrets that may have been exposed through prior command invocations.
  9. Ensure error messages, debug logs, and SDK exceptions never print full credentials.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (17)

Known Vulnerable Dependency: axios==1.13.4 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding

The lockfile pins axios 1.13.4, and the static analysis reports multiple advisories including SSRF-related and prototype-pollution-assisted request manipulation issues. In a wallet skill that performs network calls to a financial API, HTTP client flaws are security-relevant because they can affect request routing, credential handling, or trust boundaries even if the vulnerable code is transitive.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
80% confidence
Finding

form-data 4.0.5 is reported as vulnerable to CRLF injection via unescaped multipart field names/filenames. While exploitability depends on whether the skill builds multipart requests from untrusted input, retaining the vulnerable package in a financial automation skill increases risk because malformed outbound requests can be abused for header or body injection in certain integrations.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
93% confidence
Finding

The method directly creates a USDC transfer once called, with only basic address-format validation and no built-in confirmation, recipient verification, or amount sanity checks. In a wallet skill, this makes accidental, misrouted, or prompt-induced irreversible asset transfers much more likely because the code exposes a high-risk transaction primitive without a safety interlock.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 7)May include surrounding context.

md
## Features

- Create SCA wallets (Smart Contract Accounts)
- Check USDC balances across multiple chains
- Send USDC to any address
- Gas-free transactions via Circle Gas Station

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup instructions tell users to pass API keys and entity secrets directly on the command line without warning that these values are sensitive. Command-line secrets can be exposed through shell history, process listings, terminal logs, screenshots, or agent transcripts, risking wallet compromise and unauthorized transactions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation demonstrates live fund-transfer commands but does not warn that blockchain transfers are irreversible or require explicit user confirmation before execution. In an agent context, this increases the chance of accidental or socially engineered transfers because the examples normalize direct sending without a safety checkpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest advertises a circle-wallet:send command for moving funds, but this package metadata provides no user-facing warning, confirmation requirement, or indication that transfers may be irreversible. In a wallet-management skill, exposing transfer capability without prominent safety messaging increases the chance of accidental or socially engineered fund movement by users or higher-level agents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The setup flow generates an entity secret, sends it to a remote Circle registration endpoint, and then saves both the API key and generated secret locally, but the user is not explicitly warned that sensitive material will be transmitted and persisted. Because this skill manages real wallet infrastructure, silent handling of secrets is more dangerous than in a low-risk CLI: compromise of local config or misunderstanding by operators could enable unauthorized wallet actions or account takeover.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The configure command accepts a Circle API key and entity secret on the command line, then persists them locally via saveConfig(...) without any explicit warning, consent prompt, or visible safeguards. In a wallet-management CLI, these secrets are highly sensitive: command-line arguments may be exposed via shell history or process inspection, and local storage of long-lived credentials increases the blast radius if the workstation or agent environment is compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code persists wallet configuration data to a predictable file under the user's home directory without any visible warning, consent flow, or safeguards around what may be stored there. In a wallet-related skill, configuration often includes sensitive values such as API keys, wallet identifiers, or other secrets, so silent persistence increases the risk of unintended credential exposure through local compromise, backups, or misconfigured file permissions.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: follow-redirects==1.15.11 — 1 advisory(ies): CVE-2026-40895 (follow-redirects leaks Custom Authentication Headers to Cross-Domain Redirect Ta)

Low
Category
Supply Chain
Confidence
89% confidence
Finding

follow-redirects 1.15.11 is flagged for leaking custom authentication headers across cross-domain redirects. This is particularly relevant in a wallet-related skill because API keys, bearer tokens, or other auth headers used for Circle API calls could be exposed to an attacker-controlled redirect target if redirects are followed automatically.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
80% confidence
Finding

Using a caret range for @circle-fin/developer-controlled-wallets allows automatic adoption of future minor/patch releases, which can introduce breaking behavior or a compromised upstream package into a sensitive wallet skill. Because this dependency directly affects wallet and transaction operations, supply-chain risk is more consequential than in an ordinary utility package.

Content

Scanner excerpt · package.json (reported line 30)May include surrounding context.

json
"author": "eltontay",
  "license": "MIT",
  "dependencies": {
    "@circle-fin/developer-controlled-wallets": "^10.1.0",
    "commander": "^12.1.0",
    "dotenv": "^16.4.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 31)May include surrounding context.

json
"license": "MIT",
  "dependencies": {
    "@circle-fin/developer-controlled-wallets": "^10.1.0",
    "commander": "^12.1.0",
    "dotenv": "^16.4.0"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 32)May include surrounding context.

json
"dependencies": {
    "@circle-fin/developer-controlled-wallets": "^10.1.0",
    "commander": "^12.1.0",
    "dotenv": "^16.4.0"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 35)May include surrounding context.

json
"dotenv": "^16.4.0"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.7.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 36)May include surrounding context.

json
},
  "devDependencies": {
    "@types/node": "^22.0.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.7.0"
  },
  "repository": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 37)May include surrounding context.

json
"devDependencies": {
    "@types/node": "^22.0.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.7.0"
  },
  "repository": {
    "type": "git",

Static analysis

No suspicious patterns detected.