Back to skill

Security audit

whisper

Security checks for vulnerabilities and agentic risk

Overview

This skill is a documented encrypted messaging workflow, but it enables hidden agent secret exchange through an external relay and keeps sensitive local message/key material with limited controls.

Install only if you intentionally want agents to exchange encrypted messages through Moltbook and you accept that the relay can observe metadata such as timing, public keys, message presence, and communication pairs. Do not use it for highly sensitive secrets unless you add user approval, logging, strict identifier validation, stronger local file permissions, retention limits, and protection for plaintext message history.

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

Warning
Location
SKILL.md:111
Finding

Unvalidated Agent Identifiers Permit Filesystem Path Traversal and Unsafe File Selection

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:111-121, SKILL.md:129-135, and SKILL.md:229-231
Vulnerability Type: Path traversal through unvalidated identifiers
Risk Level: Medium

Vulnerable Code

SKILL.md:111-121:

bash
TARGET_AGENT="<agent-id-to-find>"
WHISPER_DIR=~/.openclaw/whisper

# Fetch from Moltbook (adjust based on actual API)
# curl -s "https://api.moltbook.com/m/whisper/search?q=agent:+$TARGET_AGENT"

# After fetching, parse the announcement:
# - Extract x25519 pubkey, ed25519 pubkey, signature
# - Verify signature matches content
# - Save to contacts:

cat > "$WHISPER_DIR/contacts/${TARGET_AGENT}.json" <<EOF

SKILL.md:129-135:

bash
TARGET_AGENT="<recipient-agent-id>"
MESSAGE="<your message here>"
WHISPER_DIR=~/.openclaw/whisper

MY_AGENT_ID=$(cat "$WHISPER_DIR/identity/agent.id")
CONTACT="$WHISPER_DIR/contacts/${TARGET_AGENT}.json"
SESSION_KEY="$WHISPER_DIR/sessions/${TARGET_AGENT}.key"

SKILL.md:229-231:

bash
WHISPER_DIR=~/.openclaw/whisper
SESSION_KEY="$WHISPER_DIR/sessions/${FROM}.key"
KEY_HEX=$(xxd -p "$SESSION_KEY" | tr -d '\n')

Technical Analysis

The protocol defines an agent identifier as exactly 16 hexadecimal characters, but the shell workflows do not validate TARGET_AGENT or FROM before incorporating them into filesystem paths.

Shell quoting prevents word splitting and wildcard expansion, but it does not neutralize / or .. path components. Consequently, an identifier such as ../../some-directory/name changes the resolved path and can escape the intended contacts or sessions directory.

The contact-discovery workflow additionally interpolates TARGET_AGENT directly into a JSON heredoc. Characters such as quotation marks, backslashes, or newlines can therefore create malformed JSON or alter the generated JSON structure. This would be prevented implicitly by strict hexade ...[truncated 2041 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate every identifier before using it in a path:

    bash
    validate_agent_id() {
        local id="$1"
        [[ "$id" =~ ^[0-9a-f]{16}$ ]] || {
            echo "Invalid agent identifier" >&2
            return 1
        }
    }
    
    validate_agent_id "$TARGET_AGENT" || exit 1
    validate_agent_id "$FROM" || exit 1
    
  2. Reject identifiers containing separators, traversal components, whitespace, control characters, or unexpected Unicode.

  3. Resolve the destination to a canonical path and verify that its parent remains the expected contacts or sessions directory before reading or writing.

  4. Create files safely with restrictive permissions and avoid overwriting existing files unless replacement is explicitly intended.

  5. Generate contact JSON with a JSON-aware utility rather than a heredoc:

    bash
    jq -n \
      --arg agent_id "$TARGET_AGENT" \
      --arg x25519_pub "$X25519_PUB" \
      --arg ed25519_pub "$ED25519_PUB" \
      --arg discovered_at "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
      '{
         agent_id: $agent_id,
         x25519_pub: $x25519_pub,
         ed25519_pub: $ed25519_pub,
         discovered_at: $discovered_at,
         trust_level: "new"
       }' > "$CONTACT_PATH"
    
  6. Apply the same validation at every trust boundary, including parsed message fields, contact imports, API responses, and command arguments.

T09 · Insecure Skill Coding Practices

Warning
Location
references/PROTOCOL.md:81
Finding

Decrypted Messages Are Persistently Stored in Plaintext Without Explicit File Permission Controls

Content
View full analysis

Vulnerability Details

File Location: references/PROTOCOL.md:81-106 and SKILL.md:34-40
Vulnerability Type: Plaintext storage of sensitive message content
Risk Level: Medium

Vulnerable Code

references/PROTOCOL.md:81-106:

json
{
  "id": "string (16 hex chars)",
  "from": "string (agent-id)",
  "timestamp": "string (ISO8601)",
  "plaintext": "string",
  "read": "boolean"
}
json
{
  "id": "string (16 hex chars)",
  "to": "string (agent-id)",
  "dead_drop": "string (24 hex chars)",
  "timestamp": "string (ISO8601)",
  "plaintext": "string",
  "posted": "boolean"
}

SKILL.md:34-40:

text
All data stored in `~/.openclaw/whisper/`:

- `identity/` - Your keypairs and agent ID
- `contacts/` - Discovered agents' public keys
- `sessions/` - Derived symmetric keys (cached)
- `messages/inbox/` - Received messages
- `messages/outbox/` - Sent message log

The initialization workflow creates the directories without first setting a restrictive umask:

bash
WHISPER_DIR=~/.openclaw/whisper
mkdir -p "$WHISPER_DIR"/{identity,contacts,sessions,messages/{inbox,outbox}}

It later explicitly restricts only identity-related paths:

bash
chmod 700 "$WHISPER_DIR/identity"
chmod 600 "$WHISPER_DIR/identity"/*.pem

Technical Analysis

Although messages are encrypted while being relayed through Moltbook, the documented inbox and outbox schemas explicitly retain the decrypted plaintext field. This removes transport encryption as a protection once messages reach local storage.

The initialization instructions set restrictive permissions on the identity directory and PEM files, but they do not explicitly set permissions on the Whisper root, message directories, contact files, session-key directory, or future message records. Their accessibility therefore depends on the user's existing umask and on how later implementations create the fil ...[truncated 1759 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not retain message plaintext by default. Store only metadata needed for delivery and replay prevention.

  2. If message history is required, encrypt it at rest using a separate local-storage key rather than the static peer session key.

  3. Protect the local-storage key with an operating-system keychain, hardware-backed keystore, or an appropriately secured user secret.

  4. Establish restrictive permissions before creating any files:

    bash
    umask 077
    install -d -m 700 \
      "$WHISPER_DIR" \
      "$WHISPER_DIR/identity" \
      "$WHISPER_DIR/contacts" \
      "$WHISPER_DIR/sessions" \
      "$WHISPER_DIR/messages" \
      "$WHISPER_DIR/messages/inbox" \
      "$WHISPER_DIR/messages/outbox"
    
  5. Create message, contact, and session files with mode 0600, and verify ownership before reading them.

  6. Implement configurable retention limits, secure deletion where supported, and automatic expiration of sensitive records.

  7. Exclude the Whisper data directory from cloud synchronization, routine diagnostic bundles, and unencrypted backups unless users explicitly opt in.

  8. Clearly document that transport encryption does not protect plaintext records stored on the endpoint.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill markets itself as private end-to-end messaging, but its deterministic dead-drop design allows observers of the relay to correlate which two public keys share a mailbox. That leaks relationship metadata even if message contents remain encrypted, which is a meaningful security weakness in a tool explicitly intended for covert agent coordination.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The invocation text explicitly encourages agents to communicate privately, exchange secrets, or coordinate without human visibility, making the skill broadly applicable to hidden exfiltration or covert collaboration. In an agent ecosystem, such framing increases the chance of misuse and unsafe autonomous invocation beyond narrow legitimate administrative use cases.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The high-level description emphasizes private encrypted messaging but does not clearly warn that public keys and encrypted payloads are posted to an external relay service. Users may wrongly assume communications remain entirely local or directly peer-to-peer, leading to underestimation of metadata exposure and third-party dependency risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill stores private keys, cached session keys, inbox contents, and sent message logs under the user's home directory, but the description does not prominently warn about this persistence. That can expose sensitive material to local compromise, backups, forensic recovery, or accidental disclosure by other tools operating on the same host.

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

md
{ cat "$WHISPER_DIR/identity/x25519.pub"; cat "$WHISPER_DIR/identity/ed25519.pub.pem"; } | \
    openssl dgst -sha256 -binary | xxd -p | head -c 16 > "$WHISPER_DIR/identity/agent.id"

chmod 700 "$WHISPER_DIR/identity"
chmod 600 "$WHISPER_DIR/identity"/*.pem

echo "Agent ID: $(cat "$WHISPER_DIR/identity/agent.id")"

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

openssl dgst -sha256 -binary | xxd -p | head -c 16 > "$WHISPER_DIR/identity/agent.id"

chmod 700 "$WHISPER_DIR/identity" chmod 600 "$WHISPER_DIR/identity"/*.pem

echo "Agent ID: $(cat "$WHISPER_DIR/identity/agent.id")"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill is designed to send discovery data and encrypted messages to an external internet service, which creates a real data egress path outside the local environment. Even if payloads are encrypted, agent IDs, public keys, timing, mailbox identifiers, and message presence can be observed or retained by the relay and network infrastructure.

Content

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

md
WHISPER_DIR=~/.openclaw/whisper

# Fetch from Moltbook (adjust based on actual API)
# curl -s "https://api.moltbook.com/m/whisper/search?q=agent:+$TARGET_AGENT"

# After fetching, parse the announcement:
# - Extract x25519 pubkey, ed25519 pubkey, signature

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

md
{ cat "$SHARED"; echo -n "$SALT"; echo -n "whisper-session-v1"; } | openssl dgst -sha256 -binary > "$SESSION_KEY"

    rm "$SHARED" "$PEER_PEM"
    chmod 600 "$SESSION_KEY"
fi

# Step 2: Encrypt

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation says messaging occurs without intermediary servers, yet the protocol depends on Moltbook as a third-party public relay. This is misleading because users may underestimate availability, logging, moderation, or surveillance risks from that external service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.