Back to skill

Security audit

Wip 1password Private

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed 1Password integration, but its MCP server can turn tool arguments into local shell commands while holding the service-account token.

Install only if you intend to give agents access to a narrowly scoped 1Password service account. Use a custom vault, prefer read_items only, avoid enabling write_items unless required, rotate the token if exposed, and do not enable the MCP server until the shell-command construction is fixed to use argument-vector execution and input validation.

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

T09 · Insecure Skill Coding Practices

Error
Location
mcp-server.mjs:24
Finding

Shell Command Injection Through MCP Tool Arguments

Content
View full analysis

Vulnerability Details

File Location: mcp-server.mjs, lines 24–29 and 76–89
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

js
function opExec(args) {
  const token = getSAToken();
  return execSync(`op ${args}`, {
    env: { ...process.env, OP_SERVICE_ACCOUNT_TOKEN: token },
    encoding: "utf8",
    timeout: 15000,
  }).trim();
}

The MCP handlers construct the args value using untrusted tool parameters:

js
case "op_read_secret": {
  const vault = args.vault || DEFAULT_VAULT;
  const field = args.field || "api key";
  const ref = `op://${vault}/${args.item}/${field}`;
  const value = opExec(`read "${ref}"`);
  return {
    content: [{ type: "text", text: value }],
  };
}

case "op_list_items": {
  const vault = args.vault || DEFAULT_VAULT;
  const result = opExec(`item list --vault "${vault}" --format json`);
  const items = JSON.parse(result);
  const summary = items.map(i => `- ${i.title} (${i.category})`).join("\n");
  return {
    content: [{ type: "text", text: summary || "No items found." }],
  };
}

Technical Analysis

The MCP-controlled item, vault, and field parameters are interpolated into a command string passed to execSync(). By default, execSync() executes the string through a system shell.

Placing input inside double quotes does not make it safe. An attacker can supply a quotation mark to terminate the intended argument and append shell operators and another command. No allowlist validation or shell-safe argument separation is applied.

The child process also receives:

js
env: { ...process.env, OP_SERVICE_ACCOUNT_TOKEN: token }

Consequently, an injected command inherits both the 1Password service-account token and every environment variable available to the MCP server.

Attack Path

  1. An attacker or compromised agent invokes op_read_secret or op_list_items.
  2. The attacker places shell syntax in a parameter, such as an item value conceptually shap ...[truncated 1355 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace shell-based execSync() with an argument-vector API such as execFileSync():

    js
    import { execFileSync } from "node:child_process";
    
    function opExec(args) {
      const token = getSAToken();
      return execFileSync("op", args, {
        env: { ...process.env, OP_SERVICE_ACCOUNT_TOKEN: token },
        encoding: "utf8",
        timeout: 15000,
        shell: false,
      }).trim();
    }
    
  2. Pass every value as a distinct argument rather than constructing command strings:

    js
    const value = opExec(["read", ref]);
    
    const result = opExec([
      "item",
      "list",
      "--vault",
      vault,
      "--format",
      "json",
    ]);
    
  3. Validate MCP parameters before invocation:

    • Require strings of reasonable maximum length.
    • Reject control characters, null bytes, and line breaks.
    • Validate 1Password references according to the supported vault, item, and field syntax.
    • Reject unexpected object or array values.
  4. Avoid relying on manual shell escaping. Argument-vector execution with shell: false should be the primary security boundary.

  5. Minimize the child environment. Pass only variables required by op, rather than copying all of process.env, where operationally possible.

  6. Configure the 1Password service account with access only to required custom vaults. Grant read_items by default and add write_items only when write functionality is explicitly required.

  7. Add regression tests using quotation marks, command separators, command substitutions, newlines, and platform-specific shell metacharacters. Tests should verify that these values are either rejected or delivered to op as literal single arguments.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (52)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The tool exposes a direct secret-reading capability and returns the decrypted value verbatim to the caller with no confirmation, scoping checks, or redaction. In an MCP context, any connected agent or prompt-induced action that can invoke this tool may exfiltrate 1Password secrets, making prompt injection or tool misuse especially dangerous.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @hono/node-server==1.19.9 — 3 advisory(ies): CVE-2026-39406 (@hono/node-server: Middleware bypass via repeated slashes in serveStatic); GHSA-frvp-7c67-39w9 (Node.js Adapter for Hono: Path traversal in `serve-static` on Windows via encode); CVE-2026-29087 (@hono/node-server has authorization bypass for protected static paths via encode)

High
Category
Supply Chain
Confidence
95% confidence
Finding

The lockfile pins @hono/node-server to 1.19.9, and the cited advisories describe path traversal and authorization/middleware bypass issues in static file serving. Even though this file is only a dependency manifest, the vulnerable package is genuinely present and could become exploitable if the skill exposes HTTP endpoints or static assets through the affected adapter.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @mariozechner/pi-coding-agent==0.52.7 — 3 advisory(ies): CVE-2026-54326 (Pi Agent: Potential XSS in HTML session exports via Markdown URL sanitization by); CVE-2026-54328 (Pi Agent: Predictable temporary extension install paths allow local privilege es); CVE-2026-54327 (Pi Agent: Race condition in Pi auth.json writes could expose stored credentials)

High
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency tree includes @mariozechner/pi-coding-agent 0.52.7, which is flagged for XSS in HTML exports, predictable temporary extension paths, and credential exposure via race conditions. In an agent/skill ecosystem, a coding-agent package can plausibly process untrusted content and local credentials, so these issues are materially relevant if that functionality is installed or invoked.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The plugin-level description says it will 'Read secrets from 1Password', which implies a read-only capability. However, the registered tool op_write_secret later creates new items and updates existing items in 1Password, expanding behavior beyond the stated description.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

Scanner excerpt · README.md (reported line 62)May include surrounding context.

md
### Can I use this?

**Yes, freely:**
- Use any tool locally or on your own servers
- Modify the code for your own projects
- Include in your internal CI/CD pipelines
- Fork it and send us feedback via PRs (we'd love that)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This markdown file describes reading credentials and storing new secrets in vaults using a fully headless service account. Although the behavior is described functionally, it lacks an explicit user warning about modifying sensitive credential stores or the need to use a properly scoped service account, which is the kind of disclosure expected for operations affecting user data and system integrity.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The setup instructions tell users to persist a long-lived 1Password service account token in ~/.openclaw/secrets/op-sa-token, creating a durable credential on disk. Even with chmod 600, filesystem persistence increases exposure to local compromise, backups, shell-history mistakes, malware, or accidental inclusion in migrations and home-directory syncs; in this context the token enables headless secret access, making the persisted credential especially sensitive.

Content

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

bash
# 1. Save service account token
mkdir -p ~/.openclaw/secrets
echo "ops_..." > ~/.openclaw/secrets/op-sa-token
chmod 600 ~/.openclaw/secrets/op-sa-token

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

Giving agents on-demand read and especially write access to a secrets vault materially expands what an agent session can do if prompted, compromised, or misconfigured. In this context, secret discovery, retrieval, and mutation capabilities increase the blast radius of prompt injection or tool misuse because the agent can access or alter credentials for other systems.

Content

Scanner excerpt · TECHNICAL.md (reported line 5)May include surrounding context.

md
## What it does

1. **Gives agents tools to read and write secrets on demand** ... Agents call `op_read_secret` to pull a key from 1Password at runtime, `op_list_items` to discover what's available, or `op_write_secret` to store new credentials.

2. **MCP server for Claude Code** ... `mcp-server.mjs` provides 1Password access directly from Claude Code via MCP. Uses the `op` CLI with service account token.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill exposes a write-capable secret-management operation that can create or overwrite credentials, but the surrounding guidance does not prominently warn about the integrity and operational risks of modifying secrets. In an agent context, this increases the chance of accidental credential rotation, corruption, or insertion of attacker-controlled values that disrupt downstream systems.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The write-support section instructs users to create a non-expiring service account with write_items permission, creating durable agent-mediated ability to modify credentials. Persistent write-capable access raises the risk of long-lived compromise, accidental secret tampering, and difficult-to-detect integrity issues if the token is stolen or the agent is manipulated.

Content

Scanner excerpt · TECHNICAL.md (reported line 181)May include surrounding context.

openclaw op-secrets resolve ~/.openclaw/openclaw.json

text

## Write Support

To enable write operations (`op_write_secret`), the service account needs `write_items` permission:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation makes contradictory security claims: it says secrets are never cached, then later recommends caching resolved secret values in memory. This can mislead operators and developers about the actual lifetime of sensitive data, increasing the chance that secrets remain resident longer than expected and are exposed through memory inspection, crashes, or reuse across tasks.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The guidance to cache resolved secrets for the session increases secret residency in process memory and may broaden exposure if the process is inspected, crashes, or handles multiple trust domains. While common for performance, in an agent setting it reduces the security benefit of just-in-time retrieval and can make cross-task leakage more likely.

Content

Scanner excerpt · TECHNICAL.md (reported line 355)May include surrounding context.

md
1. **1Password account with service account support.** All plans offer service accounts. Headless confirmed on Teams and Business.
2. **Never hardcode secrets.** Use `op://` references in config, resolve at runtime.
3. **Never log secrets.** Use the `redact()` helper for debug output.
4. **Cache the client.** Creating a 1Password SDK client is expensive (~200ms). Create once, reuse.
5. **Cache resolved values.** Secrets don't change mid-session. Resolve once at startup.
6. **Service account token location:** Always `~/.openclaw/secrets/op-sa-token`. Don't invent new paths.
7. **Vault name:** `Agent Secrets` is the shared vault. Add items there unless you need isolation.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · CHANGELOG.md (reported line 142)May include surrounding context.

md
|-----------|------|--------|
| Module | `dist/index.js` | Existing |
| OpenClaw Plugin | `openclaw.plugin.json` | Existing |
| Skill | `skills/op-secrets/SKILL.md` | Existing |
| MCP Server | `mcp-server.mjs` | **New** |
| Root Skill | `SKILL.md` | **New** |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · _trash/RELEASE-NOTES-v0-2-0.md (reported line 30)May include surrounding context.

md
|-----------|------|--------|
| Module | `dist/index.js` | Existing |
| OpenClaw Plugin | `openclaw.plugin.json` | Existing |
| Skill | `skills/op-secrets/SKILL.md` | Existing |
| MCP Server | `mcp-server.mjs` | **New** |
| Root Skill | `SKILL.md` | **New** |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · docs/DEVELOPMENT.md (reported line 288)May include surrounding context.

md
|-----------|------|--------|
| Module | `dist/index.js` | Existing |
| OpenClaw Plugin | `openclaw.plugin.json` | Existing |
| Skill | `skills/op-secrets/SKILL.md` | Existing |
| MCP Server | `mcp-server.mjs` | **New** |
| Root Skill | `SKILL.md` | **New** |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · docs/DEVELOPMENT.md (reported line 290)May include surrounding context.

md
|-----------|------|--------|
| Module | `dist/index.js` | Existing |
| OpenClaw Plugin | `openclaw.plugin.json` | Existing |
| Skill | `skills/op-secrets/SKILL.md` | Existing |
| MCP Server | `mcp-server.mjs` | **New** |
| Root Skill | `SKILL.md` | **New** |

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

Providing agents with runtime tools to read, enumerate, and especially write secrets materially expands the blast radius if an agent is prompt-injected, compromised, or misconfigured. In agent skill context this is more dangerous than ordinary application code because the exposed operations become available through natural-language-driven workflows, increasing the chance of unauthorized secret access or tampering.

Content

Scanner excerpt · ai/_trash/README--before-format--2026-03-12.md (reported line 9)May include surrounding context.

md
1. **Resolves `op://` references in `openclaw.json` at startup** — Replace plaintext API keys with `op://Agent Secrets/Item/field` references. The plugin resolves them to real values in memory when OpenClaw boots. The plaintext key never touches disk.

2. **Gives agents tools to read and write secrets on demand** — Agents call `op_read_secret` to pull a key from 1Password at runtime, `op_list_items` to discover what's available, or `op_write_secret` to store new credentials.

3. **CLI for diagnostics** — `openclaw op-secrets test` verifies 1Password connectivity. `openclaw op-secrets read` shows a redacted preview of any secret.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The documented write support uses a service account with non-expiring credentials and write_items permission, enabling persistent secret modification. If that token is exposed or an agent misuses the write tool, an attacker can implant, replace, or poison credentials in a durable way, affecting future sessions and downstream systems.

Content

Scanner excerpt · ai/_trash/README--before-format--2026-03-12.md (reported line 182)May include surrounding context.

openclaw op-secrets resolve ~/.openclaw/openclaw.json

text

## Write Support

To enable write operations (`op_write_secret`), the service account needs `write_items` permission:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The documentation claims secrets are never written outside memory or logs, but the shell examples pass secrets via environment-variable assignment and command substitution. Those patterns can expose secrets to shell history, process environments, child processes, debugging tools, or accidental terminal/log capture, so the guarantees in the README are overstated.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README makes contradictory security claims: it says secrets are never cached, but elsewhere explicitly recommends caching resolved values. This can mislead implementers into storing secrets in process memory longer than expected, weakening the stated security model and increasing exposure through memory inspection, crashes, or debugging artifacts.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
79% confidence
Finding

The guidance to cache resolved secret values and reuse clients increases secret lifetime in memory and can preserve access across the session, which weakens ephemeral-secret handling. In an agent environment, longer-lived cached secrets are more likely to be exposed through unrelated tool invocations, crashes, memory dumps, or debugging facilities.

Content

Scanner excerpt · ai/_trash/README--before-format--2026-03-12.md (reported line 356)May include surrounding context.

md
1. **Use your 1Password account with service account support** (Teams, Business, or Enterprise).
2. **Never hardcode secrets.** Use `op://` references in config, resolve at runtime.
2. **Never log secrets.** Use the `redact()` helper for debug output.
3. **Cache the client.** Creating a 1Password SDK client is expensive (~200ms). Create once, reuse.
4. **Cache resolved values.** Secrets don't change mid-session. Resolve once at startup.
5. **Service account token location:** Always `~/.openclaw/secrets/op-sa-token`. Don't invent new paths.
6. **Vault name:** `Agent Secrets` is the shared vault. Add items there unless you need isolation.

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 · docs/DEVELOPMENT.md (reported line 22)May include surrounding context.

md
This is a one-time admin task, not code.

### 0.1 Create a custom vault

Service accounts **cannot** access built-in vaults (Shared, Employee, Private). You must create a custom vault.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

mkdir -p ~/.openclaw/secrets

Paste the token into this file:

nano ~/.openclaw/secrets/op-sa-token chmod 600 ~/.openclaw/secrets/op-sa-token

text

### 0.4 Verify

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · ai/_trash/README--before-format--2026-03-12.md (reported line 60)May include surrounding context.

mkdir -p ~/.openclaw/secrets

Paste the token into this file:

nano ~/.openclaw/secrets/op-sa-token chmod 600 ~/.openclaw/secrets/op-sa-token

text

### 0.4 Verify

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · docs/DEVELOPMENT.md (reported line 54)May include surrounding context.

mkdir -p ~/.openclaw/secrets

Paste the token into this file:

nano ~/.openclaw/secrets/op-sa-token chmod 600 ~/.openclaw/secrets/op-sa-token

text

### 0.4 Verify

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
mcp-server.mjs:26