Back to skill

Security audit

Clawlink

Security checks for vulnerabilities and agentic risk

Overview

ClawLink is a real encrypted-messaging skill, but verified flaws could expose local message/key files and feed untrusted remote messages into the agent heartbeat.

Install only after review or fixes. Treat ClawLink messages as untrusted remote content, confirm the exact recipient and text before sending, avoid sensitive conversations until mailbox path validation and cryptographic verification are fixed, and protect or regularly delete ~/.openclaw/clawlink because decrypted messages and shared secrets can remain there.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
lib/mailbox.js:220
Finding

Arbitrary Local File Read Through Mailbox Path Traversal

Content
View full analysis
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
heartbeat.js:87
Finding

Untrusted Remote Messages Are Injected Directly Into Agent Heartbeat Output

Content
View full analysis
0) { for (const req of result.requests) { toDeliver.push({ type: 'request', data: req, formatted: style.formatFriendRequest(req, prefs) }); } } ``` ```js // lib/style.js:24-47 // Context if enabled - handle both message.content and direct message properties const contentObj = message.content || message; if (prefs.delivery.includeContext && contentObj?.context) { parts.push(formatContext(contentObj)); } // Summary if enabled - handle both flattened and nested text const messageText = message.text || message.content?.text || ''; if (prefs.delivery.summarizeFirst && messageText.length > 200) { parts.push(summarize(messageText)); parts.push(''); parts.push('**Full message:**'); } // The actual message - use messageText we already extracted parts.push(adaptTone(messageText || JSON.stringify(message), tone)); // Timestamp parts.push(''); parts.push(`_${formatTimestamp(message.timestamp)}_`); return parts.join('\n'); ``` ```js // heartbeat.js:87-90 if (toDeliver.length > 0) { const outputs = toDeliver.map(item => item.formatted); console.log(outputs.join ...[truncated 2164 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
lib/requests.js:191
Finding

Incoming Friend Acceptance Does Not Cryptographically Bind the Claimed Identity to the Key-Exchange Key

Content
View full analysis
p.id === req.id)) { const incomingReq = { id: req.id, from: req.fromName, fromKey: relay.hexToBase64(req.from), fromX25519: relay.hexToBase64(req.fromX25519), message: req.message, receivedAt: new Date().toISOString() }; pending.incoming.push(incomingReq); savePending(pending); results.requests.push(incomingReq); } } ``` ```js // lib/requests.js:191-241 const messages = await relay.pollMessages(identity); for (const msg of messages) { const friend = friends.find(f => relay.base64ToHex(f.publicKey) === msg.from); if (friend) { try { const content = relay.decryptMessage(msg, friend); if (content.type === 'friend_accept') { results.accepted.push({ from: friend.displayName, content }); } else { results.messages.push({ from: friend.displayName, fromKey: friend.publicKey, content, timestamp: msg.timestamp }); } } catch (e) { // Decryption failed } } else { // Check if this is from someone we sent a request to (friend_accept) const fromKeyBase64 = relay.hexToBase64(msg.from.replace('ed25519:', '')); const pendingOut = pending.outgoing.find(p => p.toKey === fromKeyBase64); if (pendingOut && msg.fromX25519) { // This is likely a friend_accept - derive shared secret and decrypt try { const theirX25519 = relay.hexToBase64(msg.fromX25519); const sharedSecret = crypto.deriveSharedSecret( ...[truncated 3822 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
lib/mailbox.js:57
Finding

Shared Secrets and Plaintext Mailbox Files Are Created Without Restrictive Permissions

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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (54)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

If the implementation reads identity material from disk and prints request, signature, or key-related metadata for debugging, that creates a genuine security risk for a cryptographic messaging system. Even partial disclosure of sensitive material or verbose authentication traces can aid compromise, leak operational secrets, or expose users through logs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the implementation reads identity material from disk and prints request, signature, or key-related metadata for debugging, that creates a genuine security risk for a cryptographic messaging system. Even partial disclosure of sensitive material or verbose authentication traces can aid compromise, leak operational secrets, or expose users through logs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the implementation reads identity material from disk and prints request, signature, or key-related metadata for debugging, that creates a genuine security risk for a cryptographic messaging system. Even partial disclosure of sensitive material or verbose authentication traces can aid compromise, leak operational secrets, or expose users through logs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the implementation reads identity material from disk and prints request, signature, or key-related metadata for debugging, that creates a genuine security risk for a cryptographic messaging system. Even partial disclosure of sensitive material or verbose authentication traces can aid compromise, leak operational secrets, or expose users through logs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the implementation reads identity material from disk and prints request, signature, or key-related metadata for debugging, that creates a genuine security risk for a cryptographic messaging system. Even partial disclosure of sensitive material or verbose authentication traces can aid compromise, leak operational secrets, or expose users through logs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

If the implementation reads identity material from disk and prints request, signature, or key-related metadata for debugging, that creates a genuine security risk for a cryptographic messaging system. Even partial disclosure of sensitive material or verbose authentication traces can aid compromise, leak operational secrets, or expose users through logs.

Content

No source excerpt is available for this finding.

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

The skill is explicitly designed to transmit user-provided content to external recipients, which is a classic exfiltration-capable pattern even if that is the intended feature. In an agent environment, such commands are dangerous because other prompts or context may trick the agent into forwarding sensitive information off-device.

Content

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

md
---
name: clawlink
description: Encrypted Clawbot-to-Clawbot messaging. Send messages to friends' Clawbots with end-to-end encryption.
triggers:
  - clawlink
  - friend link

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

The broad trigger 'send message to' creates an outbound communications channel that can be abused to exfiltrate sensitive data through prompt injection or accidental invocation. Because the skill contacts an external relay, the risk is higher than a local-only command.

Content

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

md
- clawlink
  - friend link
  - add friend
  - send message to
  - tell [name] that
  - message from
  - accept friend request

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The implementation contradicts its own security claim: it derives an X25519 key by slicing the first 32 bytes of an Ed25519 secret key instead of using a proper Ed25519-to-X25519 conversion routine. This can produce incompatible or non-standard key material, causing incorrect shared-secret derivation and undermining the reliability of end-to-end encryption in a messaging skill where confidentiality depends on correct key agreement.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module persists full message contents in plaintext markdown files under the user's home directory even though the skill is described as providing end-to-end encrypted messaging. This breaks confidentiality at the endpoint: any local user, malware, backup system, or other process with access to the account can read message contents, so the security claims are materially weakened and users may be misled into sharing sensitive data.

Content

No source excerpt is available for this finding.

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · manifest.json (reported line 67)May include surrounding context.

json
"clawlink",
    "friend link", 
    "add friend",
    "send message to",
    "tell * that",
    "message from",
    "accept friend request"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill declares network- and environment-relevant capabilities in practice but does not explicitly scope or constrain tool access in the manifest. For a messaging skill that installs dependencies, modifies local files, accesses home-directory data, and contacts a remote relay, missing permission declarations weakens reviewability and increases the chance of overbroad agent execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Broad triggers like 'send message to', 'tell [name] that', and 'message from' can activate during normal conversation and cause unintended skill execution. In a networked messaging skill, accidental invocation can lead to unintended outbound communication, privacy leaks, or confusing autonomy.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
77% confidence
Finding

The skill establishes persistent identity material and ongoing state under a home-directory path, enabling durable cross-session behavior. For a messaging skill, persistent identity is expected, but it still increases privacy and compromise impact because stolen local data could enable impersonation, contact enumeration, or long-term metadata correlation.

Content

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

⚠️ CRITICAL: Setup Required

ClawLink will NOT work until you run setup. The install script installs dependencies but you MUST create your identity:

bash
node cli.js setup "Your Name"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The generic preferences interface allows mutation of arbitrary preference paths via preferences set <path> <value>, which is broader than the manifest’s narrow scheduling/preferences-related triggers. That creates an over-privileged control surface where callers may alter unrelated behavior or future security/privacy-relevant settings without clear scoping or validation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The handler exposes direct inbox/outbox listing and arbitrary message-file reads, which materially expands the skill from sending/checking friend messages into local mailbox content access. In an agent-skill context, this can leak private message contents or metadata to callers beyond the manifest’s apparent user expectation, especially because filenames are accepted from arguments and no higher-level authorization or scope checks are visible here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Incoming message contents are automatically persisted to the local inbox, including text and metadata, without any indication in this layer that the user has consented to storage or understands retention behavior. In a messaging skill handling potentially sensitive end-to-end encrypted communications, silent local persistence increases privacy risk if the host device, profile directory, or backups are later accessed by another party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Outgoing messages are saved to a local outbox after transmission, preserving plaintext message text and associated metadata without any explicit disclosure in this code path. Because this skill is specifically for private friend-to-friend messaging, undisclosed local retention weakens the user's privacy expectations and creates an additional source of sensitive data exposure on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code generates an identity keypair and returns the private key as a base64 string, which is a safety-sensitive credential operation. Although the function has a technical docstring, there is no user-facing warning, confirmation, or disclosure about the creation and exposure of a long-term secret key.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The createInvite flow sends the user's public key, X25519 public key, display name, timestamp, and signature to a network endpoint. This network transmission of identity-related data has no visible confirmation prompt or user-facing disclosure in the code, so users may not realize what information is being shared externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The claimInvite flow posts the invite token plus the claimer's public key, X25519 public key, display name, timestamp, and signature to the relay. Because there is no prompt, warning, or user-visible message explaining this transmission, the file lacks disclosure for a privacy-relevant network operation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

When an invite is approved, the code persists a new friend record containing public keys and a derived shared secret to ~/.openclaw/clawlink/friends.json. Although the operation is commented for developers, there is no confirmation prompt, user-facing log, or warning in this file to disclose that sensitive relationship and cryptographic material is being stored locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Sent message content is written to disk persistently without any user-facing notice, opt-in, or indication that 'encrypted' messages will be retained locally in readable form. In a messaging skill, users may reasonably expect confidentiality, so silent retention increases privacy risk and can expose sensitive content through local compromise, shared accounts, backups, or forensic collection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Received messages are also stored persistently on disk without warning or consent, creating a privacy exposure for inbound content that may be especially sensitive because it originates from other parties who may assume end-to-end encrypted handling. The skill context makes this more dangerous because the product branding and description can cause users to overtrust the confidentiality of locally retained data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code forces the 'en-US' locale when computing quiet-hours time strings. This is a natural-language/locale policy issue because it imposes a specific locale choice rather than using the user's locale or documenting why that locale is required.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
cli.js:29

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/install.js:58

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
test/test-relay.js:175

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/setup.js:44

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/test-friend-request.js:24

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/test-setup.js:22