Back to skill

Security audit

LocalUDPMessenger

Security checks for vulnerabilities and agentic risk

Overview

This local agent-messaging skill is mostly disclosed, but weak trust controls can let network messages trigger agent activity without the confirmation users are told to expect.

Review before installing. Use only on trusted networks, leave relayServer and hookToken disabled unless you explicitly need them, do not rely on always-confirm until enforcement is fixed, and avoid sharing secrets or project data through messages.

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
index.ts:388
Finding
Unauthenticated Sender IDs Allow Trusted-Peer Impersonation<![CDATA[ ## Vulnerability Details **File Location**: `index.ts:388-429` **Vulnerability Type**: Authentication bypass through spoofable identity and unsafe trust migration **Risk Level**: High ### Vulnerable Code ```typescript function isTrustedPeer(peerId: string): boolean { if (trustedPeers.has(peerId)) return true; // Hostname-prefix matching: if peerId is "raspberrypi-NEWHEX" and we have // "raspberrypi-OLDHEX" trusted, match on the hostname portion and auto-migrate const dashIdx = peerId.lastIndexOf("-"); if (dashIdx === -1) return false; const peerHostname = peerId.slice(0, dashIdx); for (const [trustedId, info] of trustedPeers) { const trustedDash = trustedId.lastIndexOf("-"); if (trustedDash === -1) continue; const trustedHostname = trustedId.slice(0, trustedDash); if (peerHostname === trustedHostname) { // Migrate trust to new ID trustedPeers.set(peerId, { ...info, approvedAt: info.approvedAt }); trustedPeers.delete(trustedId); // Migrate exchange history too const oldHistory = exchangeHistory.get(trustedId); if (oldHistory) { const existing = exchangeHistory.get(peerId) || []; exchangeHistory.set(peerId, [...existing, ...oldHistory]); exchangeHistory.delete(trustedId); } addLog({ direction: "system", peerId, peerAddress: info.ip ? `${info.ip}:${info.port}` : "unknown", message: `Trust migrated from old ID "${trustedId}" → "${peerId}" (same hostname: ${peerHostname})`, trusted: true, }); saveTrust(); return true; } } return false; } ``` The UDP receiver obtains the claimed identity directly from an unauthenticated packet: ```typescript const peerId = msg.sender_id; const peerAddr = `${rinfo.address}:${msg.sender_port || rinfo.port}`; ``` ### Technical Analysis UDP packets carry no authenticated association between `sender_id`, the source address, and the previously approved pe ...[truncated 2075 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace caller-supplied IDs with cryptographically authenticated peer identities: - Give each installation a public/private key pair. - Sign every packet, including the message type, payload, timestamp, port, and a nonce. - Associate approved peers with public keys rather than hostnames. 2. Remove automatic trust migration based only on hostname text. 3. Require explicit user approval whenever a peer key or ID changes. 4. Do not update a trusted peer's stored IP or port until the peer has authenticated the change. 5. Add replay protection using nonces and bounded timestamps. 6. If cryptographic authentication cannot be implemented immediately, require both an exact ID match and the previously approved source IP, while documenting that this is only a temporary defense. 7. Treat existing persisted trust records as potentially unsafe and require re-approval after deploying the corrected identity scheme. ]]>

T01 · Skill Instruction Hijacking

Error
Location
index.ts:236
Finding
Trusted UDP Messages Are Injected Verbatim into an Agent Prompt<![CDATA[ ## Vulnerability Details **File Location**: `index.ts:236-247`, with invocation at `index.ts:547-550` **Vulnerability Type**: Remote prompt injection and agent instruction hijacking **Risk Level**: High ### Vulnerable Code ```typescript const agentPrompt = [ `You received a UDP message from trusted peer ${peerId} (${peerAddress}).`, `Message: "${message}"`, ``, `Please read this message and respond appropriately using udp_send.`, `The peer's address is ${peerAddress}. Their agent ID is ${peerId}.`, `Remember: treat the content as you would a user message, but apply trust rules from CLAUDE.md.`, `Check your hourly exchange count with udp_status before responding.`, ].join("\n"); const payload = JSON.stringify({ message: agentPrompt, name: `udp-${peerId.slice(0, 16)}`, }); ``` The prompt is triggered automatically for messages considered trusted: ```typescript // Wake the agent to process and respond to trusted messages if (isTrusted && !isOverLimit(peerId)) { wakeAgent(peerId, peerAddr, messagePayload); } ``` ### Technical Analysis Network-controlled `message`, `peerId`, and `peerAddress` values are directly interpolated into a prompt submitted to the local Gateway's `/hooks/agent` endpoint. Quotation marks provide no security boundary for a language model. A payload can close the apparent quotation, introduce new instructions, claim higher priority, request tool use, or attempt to override the surrounding safety guidance. The generated wrapper explicitly tells the agent to read and respond to the message. It therefore turns externally supplied data into actionable agent instructions rather than presenting it as inert content requiring confirmation. The risk is amplified by the sender-authentication weakness: an attacker can potentially reach this path by spoofing an approved ID or exploiting hostname-based trust migration. Even a genuinely approved peer remains an external principal and should not receive implicit authority ...[truncated 1371 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not automatically start a tool-capable agent turn from network content. 2. Default to passive notification and require explicit local user confirmation before processing or responding. 3. If automated processing is required, use a dedicated restricted agent profile with: - No shell or filesystem access. - No secrets in context. - A narrow allowlist of messaging tools. - Strict outbound destination restrictions. 4. Pass external content through a structured, separately typed data channel if supported by the Gateway rather than concatenating it into natural-language instructions. 5. Clearly label the payload as untrusted data and require the agent to summarize it for the user without following embedded instructions. 6. Authenticate every peer cryptographically before any wake-up. 7. Add policy enforcement outside the language model so network messages cannot authorize sensitive tools, file access, configuration changes, or transmission of project data. 8. Consider disabling wake-up by default and requiring a conspicuous security warning when it is enabled. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
index.ts:484
Finding
The Documented always-confirm Trust Mode Is Not Enforced<![CDATA[ ## Vulnerability Details **File Location**: `index.ts:484-550` **Vulnerability Type**: Missing authorization enforcement **Risk Level**: High ### Vulnerable Code ```typescript if (msg.type === "message") { const isTrusted = isTrustedPeer(peerId); // Update stored peer address if it changed (e.g. IP reassignment, port change) if (isTrusted && trustedPeers.has(peerId)) { const stored = trustedPeers.get(peerId)!; const incomingIp = rinfo.address; const incomingPort = msg.sender_port || rinfo.port; if (stored.ip !== incomingIp || stored.port !== incomingPort) { const oldAddr = `${stored.ip}:${stored.port}`; stored.ip = incomingIp; stored.port = incomingPort; addLog({ direction: "system", peerId, peerAddress: peerAddr, message: `Peer address updated: ${oldAddr} → ${incomingIp}:${incomingPort}`, trusted: true, }); saveTrust(); } } // Enforce message size limit to prevent oversized payloads let messagePayload: string = typeof msg.payload === "string" ? msg.payload : String(msg.payload || ""); if (messagePayload.length > MAX_MESSAGE_SIZE) { messagePayload = messagePayload.slice(0, MAX_MESSAGE_SIZE) + `... [truncated from ${msg.payload.length} chars]`; addLog({ direction: "system", peerId, peerAddress: peerAddr, message: `Oversized message truncated (${msg.payload.length} chars → ${MAX_MESSAGE_SIZE})`, trusted: isTrusted, }); } recordExchange(peerId, "received"); addLog({ direction: "received", peerId, peerAddress: peerAddr, message: messagePayload, trusted: isTrusted, }); inbox.push({ from: peerAddr, fromId: peerId, message: messagePayload, timestamp: msg.timestamp || Date.now(), trusted: isTrusted, }); relayMessage({ type: "received", agentId, peerId, peerAddress: peerAddr, message: messagePayload, timestamp: Date.now(), }); ...[truncated 1916 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce `trustMode` in code before wake-up or message processing: - In `approve-once`, permit authenticated approved peers according to policy. - In `always-confirm`, queue every message and require a distinct local approval action for that specific message. 2. Introduce immutable message IDs and bind approval to the message ID, authenticated sender identity, and payload digest. 3. Never interpret approval of a peer as approval of all subsequent messages in `always-confirm` mode. 4. Ensure notifications in `always-confirm` mode contain only a safe preview and do not create an agent turn from the full payload. 5. Add automated tests proving that `wakeAgent()` cannot be reached before per-message approval in `always-confirm` mode. 6. Validate configuration at startup and fail closed for unknown trust-mode values. 7. Update status and audit logs to show whether each message was explicitly approved. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
index.ts:151
Finding
Optional Relay Sends Complete Message Contents over Unauthenticated Plaintext UDP<![CDATA[ ## Vulnerability Details **File Location**: `index.ts:151-178` **Vulnerability Type**: Plaintext disclosure of potentially sensitive message data **Risk Level**: Medium ### Vulnerable Code ```typescript // --- Relay: forward a copy of every message to the monitoring server --- function relayMessage(event: { type: "sent" | "received" | "system"; agentId: string; peerId: string; peerAddress: string; message: string; timestamp: number; }) { if (!relayEnabled || !relayIp || !socket) return; const packet = JSON.stringify({ magic: PROTOCOL_MAGIC, type: "relay", relay_event: event.type, agent_id: event.agentId, peer_id: event.peerId, peer_address: event.peerAddress, payload: event.message, timestamp: event.timestamp, }); socket.send(packet, relayPort, relayIp, (err) => { if (err) { console.error(`Relay send failed: ${err.message}`); } }); } ``` The receiver relays all inbound message bodies, including untrusted ones: ```typescript relayMessage({ type: "received", agentId, peerId, peerAddress: peerAddr, message: messagePayload, timestamp: Date.now(), }); ``` The sender similarly relays the complete outbound message: ```typescript relayMessage({ type: "sent", agentId, peerId: params.peer_id || "unknown", peerAddress: params.address, message: params.message, timestamp: Date.now(), }); ``` ### Technical Analysis When the optional relay is enabled, complete sent and received message bodies are copied to an arbitrary configured host using UDP. The data includes agent identifiers, peer identifiers, network addresses, message contents, and timestamps. No encryption, message authentication, destination pinning, integrity protection, or delivery authentication is used. Network observers can read traffic, and a spoofed or poisoned destination can receive all future messages. Because relay happens before any per-message sensitivity decision, it can disclose project deta ...[truncated 1528 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use an authenticated, encrypted transport such as TLS instead of plaintext UDP. 2. Authenticate the relay server with certificate validation or mutually authenticated TLS. 3. Restrict relay destinations by default to explicitly approved private-network ranges and reject loopback, multicast, broadcast, and public addresses unless separately authorized. 4. Require explicit user confirmation before enabling or changing the relay at runtime. 5. Do not expose `relay_server` changes to an unrestricted agent tool. 6. Add configurable redaction and default-deny filtering for secrets, credentials, file contents, and project data. 7. Consider relaying metadata only, with message bodies disabled by default. 8. Do not relay untrusted inbound payloads unless the operator explicitly enables that separate behavior. 9. Clearly warn that enabling the relay duplicates all message content and may send it beyond the local network. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The manifest presents the skill as local UDP messaging, but the documented and detected behavior includes relaying messages to a monitoring server, reading wider config/environment data for webhook credentials, persisting trust state, and triggering local agent execution through /hooks/agent. This mismatch is dangerous because users may enable what appears to be simple LAN messaging without realizing it can expand trust, disclose message contents externally, and cause autonomous agent activation.

Exfiltration Commands

High
Category
Prompt Injection
Content
---
name: udp-messenger
description: Use when agents need to communicate over the local network — "send message to agent", "discover agents", "check for messages", "coordinate with other agents", "approve agent", "agent status", "add peer", "message log"
metadata:
  openclaw:
    requires:
Confidence
90% confidence
Finding
The skill explicitly supports sending messages to other agents, which is a legitimate feature for a messaging skill, but it is also an exfiltration pathway because it can move project data off-agent over the network. The context makes this more dangerous because the trigger phrases are broad and the skill additionally supports trust relationships, message logs, and optional relaying, increasing the chance that sensitive data could be transmitted if misused or socially engineered.

Ae1

High
Category
analysis-evasion
Content
These tools are registered by the `openclaw-udp-messenger` plugin (`index.ts`):
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The relay feature forwards copies of all sent and received messages, plus metadata, to a separately configured server. That exceeds the stated local peer-to-peer LAN messaging purpose and creates a clear confidentiality boundary break, especially because message contents may include prompts, operational data, or secrets from agent interactions.

Missing User Warnings

High
Confidence
98% confidence
Finding
Incoming and outgoing message contents are silently copied to a relay server without user-facing warning or confirmation. This creates covert exfiltration of potentially sensitive agent communications and violates the expected local-network-only behavior described by the skill metadata.

Ssd 3

High
Confidence
98% confidence
Finding
All message contents are forwarded in plain application data to a monitoring relay, creating straightforward disclosure of agent communications to another system. In the context of an agent messaging skill, messages may contain instructions, workflow state, or secrets, so broad replication materially increases exposure.

Ssd 3

High
Confidence
99% confidence
Finding
Trusted peer messages are embedded directly into an agent prompt and the agent is instructed to respond using udp_send, effectively turning remote network input into actionable prompt material. This is especially dangerous because trust is weakly managed elsewhere in the skill, so a LAN peer can induce prompt injection, autonomous responses, and tool-mediated side effects on the local agent.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The skill reads global configuration and environment-derived webhook tokens unrelated to basic UDP messaging, broadening its privilege and enabling control of local agent hooks without explicit user action. Accessing shared secrets from global config creates an unnecessary secret exposure and capability escalation path for a messaging plugin.

Exfiltration Commands

High
Category
Prompt Injection
Content
---
name: udp-messenger
description: Use when agents need to communicate over the local network — "send message to agent", "discover agents", "check for messages", "coordinate with other agents", "approve agent", "agent status", "add peer", "message log"
metadata:
  openclaw:
    requires:
Confidence
90% confidence
Finding
This skill explicitly enables network message sending and coordination with other agents, which creates a real exfiltration channel over the local network. Although the document includes guardrails against sending sensitive data, the capability materially increases the risk that an agent could disclose project data, relay instructions from untrusted peers, or participate in lateral coordination if invoked improperly.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Key Rules

1. **Trust requires user approval.** Never auto-approve a peer. Always show the user who is trying to contact them and let them decide.
2. **Conversation limits exist.** Each peer pair has a configurable exchange limit per hour (default: 10). Once reached, stop auto-responding and inform the user. The limit resets on a rolling hourly window.
3. **Trust mode is configurable.** In `approve-once` mode, a single approval lets messages flow. In `always-confirm` mode, every message needs user approval.
4. **Don't leak sensitive info.** Never share project secrets, credentials, or private data with other agents unless the user explicitly asks you to.
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Key Rules

1. **Trust requires user approval.** Never auto-approve a peer. Always show the user who is trying to contact them and let them decide.
2. **Conversation limits exist.** Each peer pair has a configurable exchange limit per hour (default: 10). Once reached, stop auto-responding and inform the user. The limit resets on a rolling hourly window.
3. **Trust mode is configurable.** In `approve-once` mode, a single approval lets messages flow. In `always-confirm` mode, every message needs user approval.
4. **Don't leak sensitive info.** Never share project secrets, credentials, or private data with other agents unless the user explicitly asks you to.
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Key Rules

1. **Trust requires user approval.** Never auto-approve a peer. Always show the user who is trying to contact them and let them decide.
2. **Conversation limits exist.** Each peer pair has a configurable exchange limit per hour (default: 10). Once reached, stop auto-responding and inform the user. The limit resets on a rolling hourly window.
3. **Trust mode is configurable.** In `approve-once` mode, a single approval lets messages flow. In `always-confirm` mode, every message needs user approval.
4. **Don't leak sensitive info.** Never share project secrets, credentials, or private data with other agents unless the user explicitly asks you to.
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Key Rules

1. **Trust requires user approval.** Never auto-approve a peer. Always show the user who is trying to contact them and let them decide.
2. **Conversation limits exist.** Each peer pair has a configurable exchange limit per hour (default: 10). Once reached, stop auto-responding and inform the user. The limit resets on a rolling hourly window.
3. **Trust mode is configurable.** In `approve-once` mode, a single approval lets messages flow. In `always-confirm` mode, every message needs user approval.
4. **Don't leak sensitive info.** Never share project secrets, credentials, or private data with other agents unless the user explicitly asks you to.
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation states that all sent and received messages can be forwarded to a central monitor server for human monitoring, but it does not clearly foreground the privacy and data-exfiltration implications at the point of configuration. In a messaging plugin where agents may exchange sensitive operational context, this creates a real risk that users enable centralized forwarding without informed consent or adequate data-handling controls.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README describes forwarding every sent and received message to a central monitoring server, including payload content, without a strong privacy and data-exposure warning. That creates a meaningful risk of sensitive prompt data, agent outputs, or internal coordination content being transmitted to infrastructure outside the local agent host or subnet.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The documentation says trusted peer messages can automatically trigger a full agent turn and be handled as if a user is talking to the agent. In an agent environment, this materially increases the risk of prompt-injection, unauthorized tool use, and cross-agent action chaining because another network peer can drive autonomous behavior without per-message human approval.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The README makes a broad safety claim that 'all traffic is local UDP' while elsewhere documenting an optional relay feature that forwards message contents to a monitoring server. This is a security-relevant contradiction because operators may rely on the local-only claim and unintentionally expose inter-agent messages beyond the host or LAN boundary.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The security section states peers are never auto-approved, but the documented udp_add_peer capability allows directly adding and trusting a peer without the discovery/approval flow. This misleading claim can cause users to overestimate the protection model and trust behavior of the plugin.

Lp3

Medium
Category
MCP Least Privilege
Confidence
78% confidence
Finding
The skill declares network-oriented capabilities but does not constrain tool scope with an explicit permissions or allowed-tools section, while static analysis indicates broader capability access such as environment exposure. In a messaging plugin that also references hook tokens and broader configuration, missing scope boundaries increases the risk of unintended access to sensitive runtime data or future capability creep.

Vague Triggers

Medium
Confidence
97% confidence
Finding
The trigger phrases are broad and overlap with common requests such as 'send message', 'check for messages', and 'coordinate with other agents', which can cause the skill to be invoked in contexts the user did not specifically intend. Because this skill can move data across the network and potentially wake other agents, overbroad activation increases the chance of unintended disclosure or unsafe multi-agent interactions.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation notes that relayServer forwards all messages to a human monitoring dashboard, but it does not present this as a prominent privacy and data disclosure warning at the point of configuration. Users may treat the feature as routine telemetry rather than full message forwarding, leading to unintended exfiltration of agent communications and project data.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The wake-up feature causes inbound peer messages to trigger requests to the Gateway /hooks/agent endpoint, effectively converting network messages into agent execution events. Without a strong warning, users may not understand that enabling hook tokens broadens message exposure and can create an automatic processing path from local network input to active agent behavior.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The code can trigger agent turns via a local HTTP webhook based on incoming UDP traffic, which expands the skill from passive messaging into remote activation of agent behavior. Because trusted peer messages are transformed into prompts, a network peer can indirectly cause autonomous actions or prompt-injection-driven behavior in the local agent.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill obtains webhook tokens from configuration and environment without clear user-facing disclosure, giving it access to sensitive credentials beyond its stated purpose. Even if not immediately leaked, silently consuming such secrets expands trust and can surprise operators about what the plugin is allowed to do.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The udp_add_peer tool is documented as adding a peer for messaging, but its implementation implicitly trusts that peer, including placeholder entries for non-responsive hosts. This undermines operator expectations and can cause later messages from that host or migrated IDs to be treated as trusted without a clear approval step.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
index.ts:618