Back to skill

Security audit

Bitwarden CLI

Security checks for vulnerabilities and agentic risk

Overview

This Bitwarden CLI skill is mostly a reference, but it recommends persistent plaintext handling of vault credentials, which makes it risky enough for review before installation.

Install only if you are comfortable giving an agent guidance for a password manager. Do not follow the persistent .secrets and shell auto-source workflow as written; prefer interactive unlocks or an OS-backed secret manager, avoid passing the master password on the command line, avoid raw/full exports unless strictly necessary, and run bw serve only on localhost for the shortest time needed.

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
SKILL.md:394
Finding

Persistent Plaintext Storage and Automatic Loading of Bitwarden Credentials

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 394-431
Vulnerability Type: Plaintext credential storage and persistent shell initialization modification
Risk Level: High

Vulnerable Code

bash
# Create .secrets file
mkdir -p ~/.openclaw/workspace
echo "BW_PASSWORD=your_master_password" > ~/.openclaw/workspace/.secrets
chmod 600 ~/.openclaw/workspace/.secrets

# Add to .gitignore
echo ".secrets" >> ~/.openclaw/workspace/.gitignore

# Auto-source in shell config (run once)
echo 'source ~/.openclaw/workspace/.secrets 2>/dev/null' >> ~/.bashrc
# OR for zsh:
echo 'source ~/.openclaw/workspace/.secrets 2>/dev/null' >> ~/.zshrc

The same file is also used to persist API credentials:

bash
# Add API credentials to .secrets
echo "BW_CLIENTID=user.xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" >> ~/.openclaw/workspace/.secrets
echo "BW_CLIENTSECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" >> ~/.openclaw/workspace/.secrets
chmod 600 ~/.openclaw/workspace/.secrets

Technical Analysis

The instructions recommend storing the Bitwarden master password and API secret as plaintext environment assignments in a persistent file. They then permanently modify .bashrc or .zshrc so that every new interactive shell sources that file.

File mode 600 and inclusion in .gitignore reduce exposure to other local users and accidental version-control commits, but they do not encrypt the credentials. Secrets remain available to any process or attacker operating under the same user account. They may also be exposed through workstation backups, endpoint inspection tools, accidental file copies, malicious shell configuration, or compromise of the user's home directory.

Automatically sourcing the file increases its exposure lifetime and makes sensitive variables available across unrelated shell sessions. Because BW_PASSWORD is the vault master password, disclosure can en ...[truncated 1716 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not store the Bitwarden master password in a persistent plaintext workspace file.
  2. Prefer interactive password entry through the CLI so the master password is not retained between sessions.
  3. For automation, retrieve credentials at runtime from an operating-system keychain, hardware-backed secret store, or dedicated secrets-management service.
  4. Do not add automatic secret-loading commands to .bashrc, .zshrc, or other persistent shell initialization files.
  5. Keep BW_SESSION short-lived, avoid persisting it, and run bw lock immediately after the required operation.
  6. If a password file is unavoidable, create it only for the operation, place it in a user-private runtime directory, enforce restrictive permissions before writing, and securely remove it afterward.
  7. Store API credentials separately from the master password and scope their availability only to the process that requires them.
  8. Retain mode 600 and version-control exclusions as defense-in-depth measures, not as substitutes for encrypted secret storage.
  9. Advise users who already followed these instructions to remove the shell startup entries, delete the plaintext file, rotate the API secret, and change the master password if exposure is suspected.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:454
Finding

Bitwarden Master Password Exposed Through Command-Line Arguments and Broad Environment Export

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 454-474
Vulnerability Type: Sensitive command-line argument exposure and excessive environment-variable propagation
Risk Level: Medium

Vulnerable Code

bash
# Login with email + password (instead of --apikey)
bw login "$BW_EMAIL" "$BW_PASSWORD"

# Or as one-liner
set -a && source ~/.openclaw/workspace/.secrets && set +a && bw login "$BW_EMAIL" "$BW_PASSWORD"

# Source the .secrets file
set -a && source ~/.openclaw/workspace/.secrets && set +a

# Try unlock first (faster, works if already logged in)
export BW_SESSION=$(bw unlock --passwordenv BW_PASSWORD --raw 2>/dev/null)

# Only login if unlock failed (vault not initialized)
if [ -z "$BW_SESSION" ]; then
  bw login "$BW_EMAIL" "$BW_PASSWORD"

Technical Analysis

The workflow supplies BW_PASSWORD as a positional argument to bw login. Shell quoting prevents word splitting but does not prevent the expanded password from becoming part of the child process's argument vector. Depending on the operating system, process isolation settings, audit configuration, tracing tools, crash reporting, and endpoint monitoring, command arguments may be observable or recorded.

The workflow also uses set -a before sourcing .secrets. This automatically exports every variable assigned by that file, not merely the Bitwarden variables required by the command. Consequently, unrelated secrets in the same file can be inherited by all subsequently launched child processes in that shell.

The later use of bw unlock --passwordenv BW_PASSWORD is safer than passing the password positionally because it avoids placing the secret directly in the argument vector. Nevertheless, environment variables remain accessible to the current process, inherited children, debuggers, crash collection systems, and same-user processes on platforms with permissive process inspection.

...[truncated 1456 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not pass the master password as a positional command-line argument. Use interactive login wherever possible.
  2. When non-interactive unlock is required, use the CLI's protected input options and obtain the secret at runtime from a trusted secret store.
  3. Remove the examples containing bw login "$BW_EMAIL" "$BW_PASSWORD" and replace them with a workflow that does not expose the password in the process argument vector.
  4. Avoid set -a when sourcing secret files. Export only the exact variables required by the immediate command.
  5. Launch sensitive commands with a minimal, explicitly constructed environment rather than allowing unrelated shell variables to propagate.
  6. Unset BW_PASSWORD, BW_CLIENTSECRET, and BW_SESSION as soon as they are no longer required, then lock the vault.
  7. Disable shell tracing before handling credentials and ensure scripts never use set -x around authentication operations.
  8. Review process-auditing, endpoint-monitoring, and crash-reporting systems to ensure command arguments and sensitive environments are not retained.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (13)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation includes full vault export commands, including JSON, ZIP, and raw output, without prominent warnings that these operations can dump all secrets and attachments to disk or stdout. In a skill that manages a password vault, providing export instructions without strong guardrails materially increases the risk of mass credential exfiltration or accidental disclosure.

Content

No source excerpt is available for this finding.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
95% confidence
Finding

Although not a backdoor in the malware sense, appending a source command to ~/.bashrc creates persistence for loading a secrets file containing Bitwarden credentials into every shell. In this skill's context, persistent secret injection is dangerous because it silently broadens credential availability and can facilitate downstream exfiltration by unrelated tools or compromised processes.

Content

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

Workspace .secrets)

Store the master password in a .secrets file in the workspace root and auto-load it:

bash
# Create .secrets file
mkdir -p ~/.openclaw/workspace
echo "BW_PASSWORD=your_master_password" > ~/.openclaw/workspace/.secrets
chmod 600 ~/.openclaw/workspace/.secrets

# Add to .gitignore
echo ".secrets" >> ~/.openclaw/workspace/.gitignore

# Auto-source in shell config (run once)
echo 'source ~/.openclaw/workspace/.secrets 2>/dev/null' >> ~/.bashrc
# OR for zsh:
echo 'source ~/.openclaw/workspace/.secrets 2>/dev/null' >> ~/.zshrc

Now BW_PASSWORD is always available:

bash
bw unlock --passwordenv BW_PASSWORD

Security requirements:

  • File must be mode 600 (user read/write only)
  • Must add .secrets to .gitignore
  • Never commit the .secrets file
  • Auto-sourcing happens on new shell sessions; run source ~/.openclaw/workspace/.secrets for current session

API Key Authentication (Workspace .secrets)

For automated/API key login, store credenti

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The export command can write the full contents of a password vault to disk or stdout, yet the documentation lacks a clear warning about the sensitivity of exported data and the risk of accidental disclosure through files, pipes, terminal capture, or downstream tools. In the context of a Bitwarden skill, this is especially dangerous because users may treat examples as safe defaults and inadvertently exfiltrate all stored secrets.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Documenting the serve command without a clear warning understates that it exposes vault functionality through a REST API, potentially broadening access from a local CLI session to a service boundary. If bound beyond localhost, used with weak origin protections, or run on a shared host, this can enable unauthorized access or abuse of unlocked vault capabilities.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger phrases are broad enough to match generic requests like 'vault', 'password manager', 'generate password', or 'get password', which can cause this high-privilege skill to activate in ambiguous contexts. In an agent ecosystem, over-broad routing increases the chance of unnecessary secret-handling or unintended access to credential-management functionality.

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

Base64 encode JSON for create/edit operations:

bash
bw get template folder | jq '.name="Test"' | bw encode | bw create folder

generate (password)

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

md
# Create .secrets file
mkdir -p ~/.openclaw/workspace
echo "BW_PASSWORD=your_master_password" > ~/.openclaw/workspace/.secrets
chmod 600 ~/.openclaw/workspace/.secrets

# Add to .gitignore
echo ".secrets" >> ~/.openclaw/workspace/.gitignore

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs users to persistently modify shell startup files so a workspace-local secrets file is sourced into every new shell. This broadens exposure of Bitwarden master password and API credentials beyond the immediate CLI task, increases accidental leakage to unrelated commands/processes, and creates lasting environment changes that can outlive the intended workflow.

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

Add API credentials to .secrets

echo "BW_CLIENTID=user.xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" >> ~/.openclaw/workspace/.secrets echo "BW_CLIENTSECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" >> ~/.openclaw/workspace/.secrets chmod 600 ~/.openclaw/workspace/.secrets

text

**Login with API key:**

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The best-practices section normalizes persistent auto-sourcing of secret-bearing environment variables across future shell sessions. Persisting Bitwarden credentials in the interactive shell environment increases the attack surface for accidental disclosure, process inheritance, shell-history mistakes, and misuse outside the intended task.

Content

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

md
3. **Secure session**: Use `bw lock` when done
4. **Protect secrets**: Never log BW_SESSION or BW_PASSWORD
5. **Secure storage**: Keep .secrets file at mode 600, never commit it
6. **Auto-source**: Add to ~/.bashrc or ~/.zshrc for persistent env vars
7. **Verify fingerprints**: Before confirming org members

## Troubleshooting

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation shows credentials being supplied via positional command-line arguments and environment variables without warning that such secrets may be exposed through shell history, process listings, logs, or inherited environments. In a password-manager skill, normalizing these patterns materially increases the chance of credential disclosure during routine use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reference states that unlock returns an export command containing the BW_SESSION key, but does not warn that this token grants vault access and can be leaked through terminal scrollback, clipboard managers, shell history, logs, or pasted transcripts. Because the session token is effectively an access credential, exposing it can enable unauthorized vault operations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes authentication, vault CRUD operations, password generation, organization management, and Send/receive, but this reference also includes import/export, server reconfiguration, update checks, and starting a local REST API server. Those are materially broader operational capabilities than the stated description and are not obviously implied by the listed use cases.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.