Back to skill

Security audit

Vault Enhancements w/ UI

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly purpose-aligned API-key management, but it handles credentials with materially overstated security claims and migration behavior that can leave plaintext secrets behind.

Review this before installing or enabling it for real credentials. It stores secrets locally in ~/.openclaw/secrets.json as plaintext JSON protected by file permissions, despite UI language saying encrypted. Do not assume migration removes every plaintext secret from openclaw.json, especially nested skill or provider keys. Also note that the included reference code can alter auth profiles and skill configuration, including skill installation flows.

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
reference/secrets-rpc.ts:34
Finding

Vault Stores Secrets as Plaintext and Does Not Enforce Permissions on Existing Files

Content
View full analysis
): Promise { const filePath = getSecretsFilePath(); await fs.mkdir(path.dirname(filePath), { recursive: true }); await fs.writeFile(filePath, JSON.stringify(secrets, null, 2) + "\n", { mode: 0o600 }); } ``` The related UI inaccurately characterizes this storage as encrypted in `reference/apikeys-views.ts:49-51`: ```ts 🔒 Encrypted keys are stored in ~/.openclaw/secrets.json (mode 0600). Config references point to the vault — the AI agent never sees your keys. ``` ### Technical Analysis The implementation serializes every API key and token directly into a JSON file without encryption. File mode `0600` is an operating-system access-control measure; it does not provide encryption at rest. Anyone who acquires readable access to the file, a filesystem snapshot, or an unencrypted backup can recover all credentials without additional key material. The `mode: 0o600` option passed to `fs.writeFile` controls permissions when a new file is created. It does not reliably correct an existing file that already has overly permissive permissions. Consequently, a vault created or replaced elsewhere with broader permissions may remain exposed after subsequent writes. The write is also performed directly against the destination file. A process interruption can leave the credential store partially written or corrupted. The local path is fixed rather than attacker-selected, but the shown implementation does not itself verify ownership, reject symbolic links, or use an atomic temporary-file replacement. The behavior is necessary insofar as the Skill must persist secrets, but plaintext storage and inaccurate encryption claims exceed an accept ...[truncated 1329 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
reference/secrets-rpc.ts:294
Finding

Nested Plaintext Secrets Are Not Removed During Migration or Individual Vault Saves

Content
View full analysis
; // Find all plaintext keys in env block const env = config.env as Record | undefined; if (!env) { respond(true, { ok: true, migrated: 0, keys: [] }); return; } const migratedKeys: string[] = []; const secrets = await readSecretsFile(); for (const [key, value] of Object.entries(env)) { // Skip if already a SecretRef if (isSecretRef(value)) continue; // Skip if not a string if (typeof value !== "string" || !value.trim()) continue; // Only migrate things that look like API keys if (!isKeyField(key)) continue; // Move to secrets file secrets[key] = value; // Replace with ref in config env[key] = makeSecretRef(key); migratedKeys.push(key); } if (migratedKeys.length === 0) { respond(true, { ok: true, migrated: 0, keys: [] }); return; } // Write secrets file await writeSecretsFile(secrets); // Ensure provider in config and write back ensureSecretsProvider(config); await fs.writeFile(configPath, JSON.stringify(config, null, 2) + "\n"); ``` The individual save path in `reference/apikeys-controller.ts:528-535` similarly converts a nested config path into a vault identifier without instructing the backend to replace the original nested field: ```ts // Extract the secret ID (env key name like OPENAI_API_KEY) const secretId = key.path[0] === "env" ? key.path[1] : key.pathStr; await state.client.request("secrets.write", { id: secretId, value: value.trim(), }); ``` ### Technical Analysis The UI recursively scans the configuration for fields matching patterns such as `apiKey`, `token`, and `secret`. The migration backend, however, only examines direct members of `config.env`. ...[truncated 2208 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented behavior claims vault-backed secret handling and reduced agent exposure, but the static finding says the implementation actually performs broader skill-management actions and may write plaintext API keys into general config. A security-sensitive skill that misrepresents secret storage behavior can cause operators to trust it with credentials under false assumptions, leading to credential disclosure or unsafe configuration changes.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · INSTALL_INSTRUCTIONS.md (reported line 17)May include surrounding context.

md
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · reference/apikeys-views.ts (reported line 50)May include surrounding context.

ts
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · reference/apikeys-views.ts (reported line 181)May include surrounding context.

ts
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · reference/apikeys-views.ts (reported line 262)May include surrounding context.

ts
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · reference/secrets-rpc.ts (reported line 12)May include surrounding context.

ts
# Vault Enhancements w/ UI v3.0.0

Vault-backed API key management for the OpenClaw Control dashboard. Keys are stored in a secure file (`~/.openclaw/secrets.json`, mode 0600) and referenced via OpenClaw's built-in Secrets System. The AI agent never sees your keys.

## Status: ✅ Active

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file states that on first key save, the system automatically creates a secrets file, configures a secret provider, and stores the key. Those behaviors affect user data and system configuration, but the installation instructions do not include any caution or disclosure about these side effects beyond describing them as automatic.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

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 304)May include surrounding context.

md
## Changelog

### v3.0.0
- **Manual "+ Add Secret" form** in Vault tab header — create vault keys without config entries
- **Vault-Only Keys section** — shows keys in vault not referenced by config
- **Restart notification banner** — yellow warning with "Restart Now" button replaces auto-reload
- **Skills vault key selector** — dropdown replaces raw password input for skills with `primaryEnv`

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The UI claims the AI agent never sees keys, but this component explicitly handles plaintext secret input and edit flows via props such as addValue, edits, onEdit, and onAddValueChange. Even if secrets are ultimately stored in a vault, they still transit the frontend state and callback chain, so the statement is materially misleading and can cause users to overtrust the system's secret isolation guarantees.

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 · reference/secrets-rpc.ts (reported line 57)May include surrounding context.

ts
// ─── Config helpers ──────────────────────────────────────────────────────────

/**
 * Read openclaw.json, apply a mutation, and write it back.
 */
async function patchConfig(
  mutate: (config: Record<string, unknown>) => void,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The secrets.write handler writes sensitive values to ~/.openclaw/secrets.json and modifies ~/.openclaw/openclaw.json, but this path contains no confirmation prompt, user-visible log, or warning string disclosing that persistent credential storage and config changes will occur. Because this operation affects user data and secret handling, the lack of explicit disclosure is a safety-relevant omission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The secrets.delete handler removes entries from the secrets file, deletes related config references, and reloads secrets, yet the code includes no confirmation prompt or visible disclosure that a destructive persistent change is being made. Deleting credentials can be irreversible from the user's perspective, so this should be explicitly surfaced.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The secrets.migrate handler scans config for plaintext keys, moves them into a secrets file, rewrites config references, and reloads secrets, but there is no embedded warning or confirmation indicating that credential locations and on-disk files will be modified. This is a safety-critical data migration affecting secret storage and configuration integrity.

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 · reference/secrets-rpc.ts (reported line 327)May include surrounding context.

ts
return;
        }

        // Write secrets file
        await writeSecretsFile(secrets);

        // Ensure provider in config and write back

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes vault-backed API key management, migration, key discovery, selector support, manual secret creation, and a settings tab. This handler goes further by deleting entire auth profiles and rewriting profile ordering, usage stats, and last-good provider state in the agent auth-profile store, which is broader account/profile lifecycle management rather than secret storage itself.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The secrets.authProfiles.delete handler deletes stored auth profile data and related metadata, then saves the updated store, but provides no user-visible warning or confirmation in this code path. Since this permanently alters credential/profile state, the operation should be clearly disclosed before execution.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes this skill as a vault-backed API keys management UI with migration, key discovery, vault-key selection, secret creation, and a settings tab. This file also invokes "skills.install" and updates skill enabled state, adding general skill lifecycle management capabilities that are not mentioned as part of the skill's purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Installing skills is a distinct administrative capability from secure storage and linking of API keys. Nothing in the manifest's stated purpose justifies a feature that can trigger remote or system-side installation workflows via "skills.install".

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.