Back to skill

Security audit

Bitwarden

Security checks for vulnerabilities and agentic risk

Overview

This Bitwarden helper is purpose-aligned, but it handles secrets with unsafe shell evaluation, broad environment capture, temp files, and persistent shell loading.

Install only if you understand that Bitwarden notes will be treated as shell code. Avoid using this with shared or editable vault items, avoid bwce unless you have reviewed the environment variables being uploaded, and consider removing eval-based loading or replacing it with strict key/value parsing before using it for real secrets.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
lib/bw-functions.sh:15
Finding

Arbitrary Shell Command Execution Through Bitwarden Secure Notes

Content
View full analysis
`. 4. `bw get item` returns the attacker-controlled note. 5. `jq` extracts the note without neutralizing shell syntax. 6. `eval` executes the note with the privileges and environment of the victim's current shell. ### Impact Assessment Successful exploitation permits arbitrary command execution with the privileges of the user who sourced the functions. The injected command could: - Read environment variables and secrets already loaded into the shell. - Access the unlocked Bitwarden CLI session through `BW_SESSION`. - Retrieve additional vault records available to the victim. - Read, modify, or delete fil ...[truncated 268 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
lib/bw-functions.sh:20
Finding

The “Safe” Secret Loader Remains Vulnerable to Command Injection

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
lib/bw-functions.sh:26
Finding

Unsafe Serialization of .env Values Creates Stored Command-Injection Payloads

Content
View full analysis
"$TMPF" bw get template item | jq --rawfile notes "$TMPF" --arg name "$1" \ '.type = 2 | .secureNote.type = 0 | .notes = $notes | .name = $name' \ | bw encode | bw create item rm -f "$TMPF" } ``` ### Technical Analysis The `awk` expression surrounds each value with single quotes but does not escape single quotes already present in the source value. It also copies the key without validating that it is a valid and permitted environment-variable name. An embedded single quote can terminate the generated quoted value. Subsequent characters then become shell syntax. Because the generated note is later consumed by the `eval`-based loaders, malformed or attacker-controlled `.env` content can become a persistent command-execution payload stored in Bitwarden. The conversion also does not distinguish comments, malformed lines, or other `.env` syntax from valid assignments. ### Attack Path 1. An attacker supplies or modifies a `.env` file that the victim uses as input to `bwc`. 2. A value contains a single quote followed by shell syntax crafted to break out of the generated assignment. 3. `bwc` inserts the value between unescaped single quotes and uploads the resulting text to Bitwarden. 4. The malicious text remains stored in the Secure Note. 5. The victim or another authorized user later runs `bwe` or `bwe_safe` for that note. 6. The loader's `eval` interprets the injected shell syntax and executes it. ### Impact Assessment The immediate operation uploads malformed secret data, while subsequent loading can result in arbitr ...[truncated 329 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
lib/bw-functions.sh:26
Finding

Plaintext Secret Temporary Files May Survive Interrupted Operations

Content
View full analysis
"$TMPF" bw get template item | jq --rawfile notes "$TMPF" --arg name "$1" \ '.type = 2 | .secureNote.type = 0 | .notes = $notes | .name = $name' \ | bw encode | bw create item rm -f "$TMPF" } # Create Secure Note from current shell exports bwce(){ local TMPF TMPF=$(mktemp) chmod 600 "$TMPF" export | awk '{print "export " $0}' > "$TMPF" bw get template item | jq --rawfile notes "$TMPF" --arg name "$1" \ '.type = 2 | .secureNote.type = 0 | .notes = $notes | .name = $name' \ | bw encode | bw create item rm -f "$TMPF" } ``` ### Technical Analysis Both functions write plaintext secrets to a temporary file. Although `chmod 600` restricts access to the owning account, cleanup occurs only through the final `rm -f` command. If the shell exits, the function is interrupted, or execution terminates before reaching that command, the temporary file can remain on disk. Examples include terminal termination, signals, system failure, or an explicit interruption during a Bitwarden operation. The `bwce` function has particularly broad exposure because it writes all exported shell variables, which may include unrelated application credentials, API keys, proxy credentials, and Bitwarden authentication variables. ### Attack Path 1. A user invokes `bwc` or `bwce`. 2. The function writes secrets into a file created under the system temporary directory. 3. The process is interrupted or terminated before the final `rm -f` executes. 4. The plaintext file remains on ...[truncated 737 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:63
Finding

Unpinned npx Installation Introduces Supply-Chain Execution Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description claims secrets stay in memory and no files touch disk, but the skill also documents deletion, exporting current shell secrets, and temporary file usage. This mismatch can cause operators or agents to make trust decisions based on inaccurate security guarantees, especially around disk exposure and destructive behavior.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

md
name: bitwarden
description: >
  Manage secrets via Bitwarden CLI (bw). Use when pulling secrets into a shell session,
  creating/updating Secure Notes from .env files, listing vault items, or setting up
  Bitwarden on a new machine. Secrets live in Bitwarden, get loaded into memory on demand,
  and die with the shell session — no files on disk.
homepage: https://bitwarden.com/help/cli/

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

md
name: bitwarden
description: >
  Manage secrets via Bitwarden CLI (bw). Use when pulling secrets into a shell session,
  creating/updating Secure Notes from .env files, listing vault items, or setting up
  Bitwarden on a new machine. Secrets live in Bitwarden, get loaded into memory on demand,
  and die with the shell session — no files on disk.
homepage: https://bitwarden.com/help/cli/

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

md
name: bitwarden
description: >
  Manage secrets via Bitwarden CLI (bw). Use when pulling secrets into a shell session,
  creating/updating Secure Notes from .env files, listing vault items, or setting up
  Bitwarden on a new machine. Secrets live in Bitwarden, get loaded into memory on demand,
  and die with the shell session — no files on disk.
homepage: https://bitwarden.com/help/cli/

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · lib/bw-functions.sh (reported line 25)May include surrounding context.

sh
name: bitwarden
description: >
  Manage secrets via Bitwarden CLI (bw). Use when pulling secrets into a shell session,
  creating/updating Secure Notes from .env files, listing vault items, or setting up
  Bitwarden on a new machine. Secrets live in Bitwarden, get loaded into memory on demand,
  and die with the shell session — no files on disk.
homepage: https://bitwarden.com/help/cli/

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

High
Category
YARA Match
Confidence
75% confidence
Finding

Appending a source line into ~/.bashrc creates persistence by causing future shells to automatically load third-party code. While this is a common convenience pattern and not clearly malicious here, it is security-relevant because any compromise of the referenced file or install path will execute on every shell startup.

Content

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

dependency.

Setup on a new machine

bash
# 1. Install bw CLI
brew install bitwarden-cli    # macOS
sudo snap install bw          # Ubuntu
npm i -g @bitwarden/cli       # any OS

# 2. Install skill (choose one)
npx clawhub install bitwarden-bwe            # via ClawHub
# or: git clone https://github.com/stevengonsalvez/clawdbot /path/to/clawdbot

# 3. Source functions in your shell profile
echo 'source /path/to/skills/bitwarden-bwe/lib/bw-functions.sh' >> ~/.bashrc
source ~/.bashrc

# 4. Login + unlock
export BW_CLIENTID="user.xxxxx"
export BW_CLIENTSECRET="xxxxx"
bw login --apikey
bwss   # unlock (prompts for master password)

# 5. Verify
bwl    # list vault items

What's in lib/bw-functions.sh

FunctionPurpose
bwssUnlock vault, set `BW

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

bwce creates Secure Notes from current shell exports, which can capture a broad set of environment variables beyond the intended secrets. In practice this can unintentionally exfiltrate tokens, cloud credentials, session values, or other sensitive runtime data into Bitwarden or logs, especially in agent or CI environments with large inherited environments.

Content

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

bash
# From a .env file
bwc my-new-project .env

# From current shell
bwce snapshot-2026-03-03

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The documented NOTES=$(cat .env | awk '{print "export " $0}') pattern blindly transforms .env content into shell syntax for later evaluation. If the .env file contains malformed or attacker-controlled values, this can propagate unsafe shell content into the Bitwarden note and later lead to command execution when loaded with bwe or even bwe_safe, which explicitly does not sanitize values.

Content

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

bash
COLLECTION_ID="<collection-uuid>"
ORG_ID="<org-uuid>"
NOTES=$(cat .env | awk '{print "export " $0}')

bw get template item | jq \
  --arg notes "$NOTES" \

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

bwe() retrieves .notes from a Bitwarden item and passes it directly to eval, allowing arbitrary shell command execution if the note content is malicious or tampered with. In this skill context, the vault content is treated as trusted configuration, which makes the dangerous behavior more likely to be used routinely and unnoticed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill description claims secrets never touch disk, but bwc() writes secret material derived from a .env file into a temporary file before uploading it to Bitwarden. Even with chmod 600, the secret exists on disk and may be exposed via backups, disk forensics, crash artifacts, or race conditions on compromised hosts.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

bwce() captures and uploads the entire current shell environment to Bitwarden without warning, which can include tokens, cloud credentials, session secrets, and unrelated sensitive data. In a secrets-management skill, this broad collection and transmission increases the blast radius of accidental exfiltration or oversharing.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

bwce() exports the current shell environment, including potentially sensitive credentials, into a temporary file before storing it in Bitwarden. This contradicts the stated security model and expands exposure of in-memory secrets to local disk artifacts.

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 · references/cli-reference.md (reported line 26)May include surrounding context.

bw login --apikey

text

Get API key from: Web Vault → Settings → Security → Keys → API Key

### Email login (interactive)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill clearly instructs use of shell commands and persistent shell integration, but it declares no explicit tool scope such as allowed shell usage. This weakens policy enforcement and user awareness, increasing the chance that an agent can invoke shell capabilities without clear authorization boundaries.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

bash
# 1. Install bw CLI
brew install bitwarden-cli    # macOS
sudo snap install bw          # Ubuntu
npm i -g @bitwarden/cli       # any OS

# 2. Install skill (choose one)

Rp1

Medium
Category
MCP Rug Pull
Confidence
80% confidence
Finding

Using npx clawhub install bitwarden-bwe without a pinned version introduces supply-chain risk because the fetched package can change over time or be replaced by a compromised release. For a secrets-management skill, this is more dangerous than usual because compromise could lead directly to credential theft or malicious shell modifications.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

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

md
### What's in `lib/bw-functions.sh`

| Function            | Purpose                                                                                   |
| ------------------- | ----------------------------------------------------------------------------------------- |
| `bwss`              | Unlock vault, set `BW_SESSION` interactively                                              |
| `bwe <name>`        | Load secrets from Secure Note into env via `eval`                                         |

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The documented bwdd delete capability is destructive and appears without a strong nearby warning about irreversibility or confirmation requirements. In a secrets-management workflow, accidental deletion can disrupt systems and cause loss of critical credential material or metadata.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
74% confidence
Finding

The skill encourages keeping BW_SESSION active for the life of the shell session and discusses writing secrets to disk if necessary. For a secrets-management skill used in terminals, tmux, or agent environments, session persistence increases the window during which a hijacked shell, inherited environment, or process inspection could expose vault access or loaded secrets.

Content

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

md
## Guardrails

- **Never paste secrets into chat, logs, or code.** Use `bwe` to load into memory only.
- **Never write secrets to disk** unless absolutely necessary (and chmod 600 if you must).
- **Prefer `bwe` over `~/.secrets/` files.** Secrets in memory > secrets on disk.
- **Use `bwe_safe` on shared/org accounts.** Defence in depth against note tampering.
- **`bwss` once per terminal session.** The session token persists until the shell exits.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comment marks bwe_safe() as safe, but it still executes Bitwarden note content with eval. Restricting input to lines matching export VAR=value reduces some attack surface, but shell expansion and command substitution inside the value can still execute attacker-controlled code when the note content is evaluated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Although presented as safer, bwe_safe() still evaluates vault-sourced content and gives users no meaningful disclosure that note text can execute shell syntax. This is dangerous because users may trust the function name and load manipulated notes that trigger command execution via value expansion.

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

md
local FF="${2:-.env}"
    local TMPF
    TMPF=$(mktemp)
    chmod 600 "$TMPF"
    awk -F= '{key=$1; val=substr($0,index($0,"=")+1); print "export " key "=\047" val "\047"}' "$FF" > "$TMPF"
    bw get template item | jq --rawfile notes "$TMPF" --arg name "$1" \
      '.type = 2 | .secureNote.type = 0 | .notes = $notes | .name = $name' \

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

md
local FF="${2:-.env}"
    local TMPF
    TMPF=$(mktemp)
    chmod 600 "$TMPF"
    awk -F= '{key=$1; val=substr($0,index($0,"=")+1); print "export " key "=\047" val "\047"}' "$FF" > "$TMPF"
    bw get template item | jq --rawfile notes "$TMPF" --arg name "$1" \
      '.type = 2 | .secureNote.type = 0 | .notes = $notes | .name = $name' \

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 · lib/bw-functions.sh (reported line 30)May include surrounding context.

sh
local FF="${2:-.env}"
    local TMPF
    TMPF=$(mktemp)
    chmod 600 "$TMPF"
    awk -F= '{key=$1; val=substr($0,index($0,"=")+1); print "export " key "=\047" val "\047"}' "$FF" > "$TMPF"
    bw get template item | jq --rawfile notes "$TMPF" --arg name "$1" \
      '.type = 2 | .secureNote.type = 0 | .notes = $notes | .name = $name' \

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 · lib/bw-functions.sh (reported line 42)May include surrounding context.

sh
local FF="${2:-.env}"
    local TMPF
    TMPF=$(mktemp)
    chmod 600 "$TMPF"
    awk -F= '{key=$1; val=substr($0,index($0,"=")+1); print "export " key "=\047" val "\047"}' "$FF" > "$TMPF"
    bw get template item | jq --rawfile notes "$TMPF" --arg name "$1" \
      '.type = 2 | .secureNote.type = 0 | .notes = $notes | .name = $name' \

Static analysis

No suspicious patterns detected.