Back to skill

Security audit

1Password Web UI

Security checks for vulnerabilities and agentic risk

Overview

This 1Password skill is mostly coherent and disclosed, but it exposes powerful secret-reading gateway methods with weak scoping and a command-injection risk in the backend example.

Review before installing. Only install this on a trusted, loopback-only or strongly authenticated gateway, use narrowly scoped 1Password vault/token permissions, do not place Connect tokens in checked-in compose files, and patch the backend to avoid shell execution and enforce per-skill secret allowlists before relying on it.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
reference/1password-backend.ts:58
Finding

Shell Command Injection Through Gateway RPC Parameters

Content
View full analysis
{ const opPath = which("op"); if (!opPath) { throw new Error("1Password CLI (op) not found in PATH"); } return execAsync(`"${opPath}" ${args.join(" ")}`, { timeout }); } ``` A representative RPC-controlled call site is the sign-in handler: ```typescript "1password.signin": async ({ params, respond }) => { try { if (isConnectMode()) { respond(true, { success: true, message: "Connect mode - no sign-in required" }, undefined); return; } const { account } = params as { account?: string }; const result = await cliSignin(account); respond(true, result, undefined); } catch (e) { respond(true, { success: false, error: e instanceof Error ? e.message : String(e) }, undefined); } }, ``` ### Technical Analysis `opCommand()` constructs a command string by joining argument values and passes that string to Node.js `exec()`. Unlike argument-array APIs, `exec()` invokes a shell. Consequently, shell metacharacters contained in an argument are interpreted as command syntax rather than passed literally to the 1Password CLI. Several arguments originate from gateway RPC parameters, including `account`, `vault`, `category`, `item`, and `field`. The code does not quote, escape, or constrain those values before inserting them into the command string. Quoting only `opPath` does not protect the remaining arguments. For example, an account value containing `x; id #` would produce a command structurally equivalent to: ```bash "/path/to/op" signin --account x; id # --force ``` The shell can therefore execute the injected comma ...[truncated 1535 chars]
Remediation
View remediation
{ const opPath = which("op"); if (!opPath) { throw new Error("1Password CLI (op) not found in PATH"); } return execFileAsync(opPath, args, { timeout, shell: false, windowsHide: true, }); } ``` 2. Validate every RPC parameter before using it: - Require non-empty strings of bounded length. - Reject control characters and null bytes. - Restrict categories to an explicit allowlist. - Where possible, require immutable 1Password UUIDs instead of arbitrary names. 3. Apply schema validation at the RPC boundary rather than relying on TypeScript casts, which provide no runtime protection. 4. Do not attempt to repair the issue solely through shell escaping. Avoiding the shell is safer and portable. 5. Add regression tests using values containing spaces, quotes, semicolons, command substitutions, pipes, redirections, and newlines. Tests should confirm that these values are passed literally or rejected and never interpreted by a shell. 6. Run the gateway under a dedicated, minimally privileged operating-system account and limit access to sensitive environment variables and files. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
reference/1password-backend.ts:435
Finding

Unrestricted Secret Retrieval Through a Gateway RPC Method

Content
View full analysis
{ // This is backend-only - used by skills, not exposed to UI directly try { const { item, field, vault } = params as { item: string; field: string; vault?: string }; let value: string; if (isConnectMode()) { if (!vault) { respond(true, { error: "vault required for Connect mode" }, undefined); return; } value = await connectReadSecret(vault, item, field); } else { value = await cliReadSecret(item, field, vault); } respond(true, { value }, undefined); } catch (e) { respond(true, { error: e instanceof Error ? e.message : String(e) }, undefined); } }, ``` ### Technical Analysis The handler accepts an arbitrary vault, item, and field from its caller and returns the corresponding plaintext secret in the gateway response. The reviewed handler performs no method-level authorization, caller identity check, per-skill allowlist enforcement, mapping restriction, user confirmation, or audit logging. The comment that the method is “backend-only” does not enforce a security boundary. The method is registered in the same `GatewayRequestHandlers` object as UI-facing methods and is explicitly declared as a provided RPC method in `package.json`. The current UI does not call it, but any client context accepted by the gateway and allowed to invoke arbitrary registered methods may attempt to do so. In CLI mode, the operation uses the gateway's authenticated 1Password session. In Connect mode, it uses the process-wide `OP_CONNECT_TOKEN`. Thus, the caller receives the privileges of the gateway's credential context rather than a narrowly scoped credential mapping. This access exceeds the minimum privileges ne ...[truncated 1681 chars]
Remediation
View remediation
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
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill is presented primarily as a UI tab, but the documentation explicitly exposes backend RPC methods for secret retrieval, vault enumeration, sign-in/sign-out, and Connect API usage. This mismatch is dangerous because operators may install it expecting presentation-only behavior, while it actually adds privileged backend secret-access functionality that materially expands the attack surface.

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 · SKILL.md (reported line 124)May include surrounding context.

md
ports:
      - "8080:8080"
    volumes:
      - ./1password-credentials.json:/home/opuser/.op/1password-credentials.json:ro
      - op-data:/home/opuser/.op/data

  op-connect-sync:

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

md
ports:
      - "8080:8080"
    volumes:
      - ./1password-credentials.json:/home/opuser/.op/1password-credentials.json:ro
      - op-data:/home/opuser/.op/data

  op-connect-sync:

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

md
ports:
      - "8080:8080"
    volumes:
      - ./1password-credentials.json:/home/opuser/.op/1password-credentials.json:ro
      - op-data:/home/opuser/.op/data

  op-connect-sync:

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

md
1. Go to [my.1password.com](https://my.1password.com) → Integrations → Secrets Automation
2. Create a Connect server
3. Download `1password-credentials.json`
4. Create an access token

### Step 3: Configure OpenClaw

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

md
| Aspect | Implementation |
|--------|----------------|
| **Secrets not in UI** | `getItem` and `items` return field names only, never values |
| **No network installers** | No `curl \| sh` or remote scripts — all code is local |
| **Manual installation** | Requires explicit code edits, no automated patching |
| **Mapping file perms** | `1password-mappings.json` should be 0600 (contains references, not secrets) |
| **CLI auth** | Uses 1Password app integration for biometric auth when available |

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · reference/1password-backend.ts (reported line 186)May include surrounding context.

ts
try {
    await opCommand(["signout"], 5000);
  } catch {
    // Ignore errors, just clear state
  }
  sessionState = { signedIn: false };
  return { success: true };

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The Docker example includes a live placeholder for OP_CONNECT_TOKEN, which is a sensitive secret, but provides no warning about secure injection, secret management, log exposure, or avoiding committing credentials to source-controlled compose files. In the context of a skill that manages secrets and authentication state, normalizing direct placement of a high-value token in configuration increases the chance operators will hardcode or leak it.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill describes and references capabilities that interact with environment variables, external services, and local command execution, yet it declares no explicit tool scope or permission boundaries. In a secrets-management skill, missing capability declarations increase the chance that reviewers or policy engines will under-estimate what the skill can access, enabling risky deployment with insufficient controls.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 197)May include surrounding context.

bash
# Recommended permissions for mapping file
chmod 600 ~/clawd/config/1password-mappings.json

Troubleshooting

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The backend exposes a generic 1password.readSecret RPC that returns raw secret values to any caller able to invoke gateway handlers, while the comment explicitly notes it is intended for skills and not UI. There is no authorization check, allowlist, audit trail, consent gate, or scope restriction tied to mappings, so compromise of a skill or abuse of the RPC interface could directly exfiltrate 1Password secrets.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/op-helper.py (reported line 62)May include surrounding context.

python
if not op_path:
        raise Exception("1Password CLI (op) not found in PATH")
    
    result = subprocess.run(
        [op_path] + args,
        capture_output=True,
        text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The read path prints the secret value directly to stdout in both Connect and CLI modes. In agent, dashboard, or automation environments, stdout is commonly captured by logs, task transcripts, wrappers, or higher-level tooling, so this design can unintentionally exfiltrate credentials far beyond the immediate caller.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The helper is described as a bridge for reading credentials, but it also exposes vault and item enumeration through 'vaults' and 'items' commands. In a secrets-management context, metadata disclosure is sensitive because it reveals account structure, vault names, and secret inventory that can help an attacker identify high-value targets and streamline later secret theft.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The file reads OP_CONNECT_TOKEN from environment variables to authenticate to 1Password Connect, which is a sensitive credential access path. There is no visible confirmation, logging, or explanatory warning in this file to disclose that the skill will consume a credential from the environment.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
reference/1password-backend.ts:25