Back to skill

Security audit

0x0 Messenger

Security checks for vulnerabilities and agentic risk

Overview

This messenger skill mostly matches its stated purpose, but its local web interface and notification code expose sensitive messaging controls and metadata with too little authentication or disclosure.

Review before installing or running the web UI. Use localhost-only mode, avoid --lan on shared networks, assume ~/.0x0 contains sensitive identity, PIN, contact, queue, and message data, and treat the notification feature as involving a centralized third-party endpoint until the publisher documents or removes it. The package should add WebSocket authentication/Origin checks, stronger warnings, and dependency updates before broad use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/web/server.js:19
Finding
Unauthenticated WebSocket API Exposes Messaging Data and Privileged Operations<![CDATA[ ## Vulnerability Details **File Location**: `src/web/server.js:19-23`; `src/web/api.js:55-72` **Vulnerability Type**: Missing authentication and WebSocket Origin validation **Risk Level**: High ### Vulnerable Code `src/web/server.js:19-23`: ```js // WebSocket: デフォルトはローカルホストのみ、--lan で LAN 公開 const wss = new WebSocketServer({ server, maxPayload: 1024 * 1024 }) wss.on('connection', (ws) => { createApiHandler(ws) }) ``` `src/web/api.js:55-72`: ```js // 接続確立時に初期データを送信 const identity = identityStore.load() if (identity) { sendEvent('init', { data: { number: identity.number, inbox: buildInbox(), contacts: buildContacts(), prefs: { theme: 'dark' } }}) } ws.on('message', async (raw) => { let msg try { msg = JSON.parse(raw.toString()) } catch { return } await dispatch(msg) }) ``` ### Technical Analysis The WebSocket server accepts every connection and immediately passes it to `createApiHandler` without authenticating the client, validating a session token, or checking the HTTP `Origin` header during the upgrade. Once connected, the API sends initialization data containing the local identity number, inbox, contacts, PIN records, message metadata, and latest messages. The same connection can submit commands handled by `dispatch`, including operations that: - List stored messages and contacts. - Send messages and files. - Create, rotate, or revoke PINs. - Add, modify, or remove contacts. - Renew the user's number. - Register notification tokens. Binding to `127.0.0.1` by default is not a sufficient authorization boundary. A malicious web page may attempt a cross-site WebSocket connection to a predictable local port. In addition, the documented `--lan` option binds the service to `0.0.0.0`, making the unauthenticated interface directly reachable by other devices on the same network. LAN traffic is also served over plaintext HTTP and WebSocket protocols. ### Attack Path 1. The victim starts the web interface using `c0x0 web`, ...[truncated 1656 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random, high-entropy session token each time the web server starts. 2. Require the token during the WebSocket upgrade, preferably through an authorization mechanism that does not expose it to unrelated origins. 3. Validate the WebSocket `Origin` header against an explicit allowlist and reject missing or unexpected origins. 4. Validate the request host and upgrade path rather than accepting WebSockets on every route. 5. For LAN mode, require explicit authentication and display a clear warning that the interface exposes private conversations and account-management operations. 6. Use TLS (`HTTPS` and `WSS`) for all non-loopback access. 7. Consider separating read-only and state-changing operations and requiring reauthorization for destructive actions such as PIN revocation or number renewal. 8. Avoid returning raw PIN values and full message details in the initial event unless they are required by the active view. 9. Add connection rate limits, command-level authorization checks, and security tests covering hostile Origin headers and unauthenticated LAN clients. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/web/api.js:13
Finding
Undisclosed Centralized Notification Registration Uses a Hardcoded Shared Key<![CDATA[ ## Vulnerability Details **File Location**: `src/web/api.js:13-14`, `src/web/api.js:207-231`, `src/web/api.js:280-286` **Vulnerability Type**: Sensitive metadata transmission and ineffective client-embedded authentication **Risk Level**: Medium ### Vulnerable Code `src/web/api.js:13-14`: ```js const WORKERS_URL = 'https://0x0-notification.tiidatech.workers.dev' const NOTIFY_KEY = '0x0-nfy-v1-c8f3a1b9' ``` `src/web/api.js:207-231`: ```js case 'notify.register': { const { token, platform } = msg const safePlatform = validatePlatform(platform) if (!token || typeof token !== 'string' || token.length > 512 || !safePlatform) break const notifyIdentity = identityStore.load() if (!notifyIdentity) break await fetch(`${WORKERS_URL}/register`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-0x0-Key': NOTIFY_KEY }, body: JSON.stringify({ number: notifyIdentity.number, token, platform: safePlatform }) }).catch(() => {}) sendEvent('notify.registered', {}) break } case 'notify.unregister': { const unregIdentity = identityStore.load() if (!unregIdentity) break await fetch(`${WORKERS_URL}/register`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-0x0-Key': NOTIFY_KEY }, body: JSON.stringify({ number: unregIdentity.number }) }).catch(() => {}) sendEvent('notify.unregistered', {}) break } ``` `src/web/api.js:280-286`: ```js // 相手に通知を送る(バックグラウンド、失敗は無視) fetch(`${WORKERS_URL}/notify`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-0x0-Key': NOTIFY_KEY }, body: JSON.stringify({ recipientNumber: contact.theirNumber }) }).catch(() => {}) ``` ### Technical Analysis The application contains a centralized notification integration that transmits messenger identifiers and push-notification tokens to an external Cloudflare Worker: - Registration links the local messenger number to an FCM or APNs token. - Unregistration sends the local messenger numbe ...[truncated 2800 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Clearly disclose the centralized notification service, the destination domain, transmitted data, purpose, retention policy, and privacy implications. 2. Require explicit, informed user consent before registering a push token or transmitting messenger identifiers. 3. Keep the notification feature disabled by default so basic P2P messaging does not contact the centralized service. 4. Remove claims such as “no servers” and “no registration,” or qualify them accurately if notification registration remains available. 5. Do not use a secret embedded in client code as an authentication control. 6. Replace the shared key with server-issued, scoped, short-lived credentials tied to authenticated registration workflows. 7. Protect registration updates against token replacement and require proof that the requester controls the relevant identity. 8. Minimize metadata by using opaque, rotating notification identifiers rather than stable messenger numbers. 9. Add rate limiting, replay protection, audit logging, and abuse monitoring to the notification service. 10. Return a failure status when remote registration fails instead of always emitting `notify.registered`, so users are not given misleading security or delivery state. 11. Resolve the WebSocket authentication vulnerability before exposing notification registration through the local API. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (96)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill states that messages may queue for 72 hours if a peer is offline, but it does not clearly disclose the privacy and persistence implications of that retention. Even if this is expected functionality, undisclosed temporary storage of message content/metadata can expose sensitive operational data to local compromise, endpoint forensics, or unexpected provider retention assumptions.

Known Vulnerable Dependency: nanoid==3.3.11 — 3 advisory(ies): CVE-2026-67214 (nanoid: non-secure generators can loop indefinitely with negative size); CVE-2026-67213 (nanoid: custom generators can loop indefinitely when size is zero); CVE-2026-73086 (nanoid: Integer Overflow or Wraparound)

High
Category
Supply Chain
Confidence
80% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Known Vulnerable Dependency: path-to-regexp==8.3.0 — 2 advisory(ies): CVE-2026-4923 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple w); CVE-2026-4926 (path-to-regexp vulnerable to Denial of Service via sequential optional groups)

High
Category
Supply Chain
Confidence
88% confidence
Finding
path-to-regexp 8.3.0 is used by router/Express and is flagged for ReDoS-style denial of service through crafted route-matching patterns. If the application constructs or evaluates attacker-influenced paths against vulnerable patterns, requests can consume excessive CPU and degrade availability. Because this skill appears to expose HTTP functionality through Express, routing-layer DoS is more relevant than in an offline tool.

Known Vulnerable Dependency: picomatch==4.0.3 — 2 advisory(ies): CVE-2026-33672 (Picomatch: Method Injection in POSIX Character Classes causes incorrect Glob Mat); CVE-2026-33671 (Picomatch has a ReDoS vulnerability via extglob quantifiers)

High
Category
Supply Chain
Confidence
80% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Known Vulnerable Dependency: postcss==8.5.6 — 4 advisory(ies): CVE-2026-45623 (PostCSS: Arbitrary file read and information disclosure via attacker-controlled ); CVE-2026-69153 (PostCSS: incomplete fix of GHSA-6g55-p6wh-862q — attacker-controlled sourceMappi); CVE-2026-41305 (PostCSS has XSS via Unescaped </style> in its CSS Stringify Output) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Known Vulnerable Dependency: rollup==4.58.0 — 1 advisory(ies): CVE-2026-27606 (Rollup 4 has Arbitrary File Write via Path Traversal)

High
Category
Supply Chain
Confidence
80% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Known Vulnerable Dependency: vite==7.3.1 — 5 advisory(ies): CVE-2026-39365 (Vite Vulnerable to Path Traversal in Optimized Deps `.map` Handling); CVE-2026-53571 (vite: `server.fs.deny` bypass on Windows alternate paths); CVE-2026-39363 (Vite Vulnerable to Arbitrary File Read via Vite Dev Server WebSocket) +2 more

High
Category
Supply Chain
Confidence
80% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
89% confidence
Finding
ws 8.19.0 is a direct production dependency, and the cited issues include memory disclosure and memory-exhaustion DoS from crafted fragmented frames. For a messaging skill that likely relies on persistent peer or browser-connected channels, hostile remote peers could potentially exploit WebSocket handling to leak process memory or exhaust resources, making this particularly relevant to the skill context.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
96% confidence
Finding
The manifest includes ws with a semver range that static analysis resolved to a known vulnerable release (8.19.0) affected by memory disclosure and memory-exhaustion denial-of-service issues. Because this skill is explicitly a messaging tool using WebSockets/P2P communication, a vulnerable ws dependency is more dangerous here than in a non-networked package: remote peers may be able to trigger information leakage or resource exhaustion through crafted traffic.

Known Vulnerable Dependency: vite==7.3.1 — 5 advisory(ies): CVE-2026-39365 (Vite Vulnerable to Path Traversal in Optimized Deps `.map` Handling); CVE-2026-53571 (vite: `server.fs.deny` bypass on Windows alternate paths); CVE-2026-39363 (Vite Vulnerable to Arbitrary File Read via Vite Dev Server WebSocket) +2 more

High
Category
Supply Chain
Confidence
91% confidence
Finding
The devDependency on Vite resolves to a version with multiple advisories, including arbitrary file read and path traversal issues in the dev server. This is somewhat mitigated because Vite is listed only as a development tool, but the package scripts expose a dev server workflow and developers may run it locally or in shared environments, creating risk of source disclosure or local file access if the dev server is reachable.

Missing User Warnings

High
Confidence
96% confidence
Finding
The revoke action sends `pin.revoke` immediately on click and then clears the active view, with no confirmation step. Because revocation is an irreversible or at least disruptive action that immediately stops receiving messages on that PIN, the absence of a final warning creates a significant risk of accidental data-flow interruption.

Memory Manipulation

High
Category
Memory Poisoning
Content
ws.on('contact.removed', (msg: unknown) => {
  const m = msg as { contactId: string }
  state.contacts = state.contacts.filter(c => c.id !== m.contactId)
  delete state.contactMessages[m.contactId]
  delete state.peerStatus[m.contactId]
  render()
})
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
ws.on('contact.removed', (msg: unknown) => {
  const m = msg as { contactId: string }
  state.contacts = state.contacts.filter(c => c.id !== m.contactId)
  delete state.contactMessages[m.contactId]
  delete state.peerStatus[m.contactId]
  render()
})
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The README documents `c0x0 web --lan` as exposing the local chat UI to the LAN but does not prominently warn that this makes the interface reachable by other devices on the same network. In a messaging tool handling sensitive chats, users may assume the web UI remains local-only and inadvertently expose message contents or control functions to untrusted peers on shared Wi‑Fi or office/home networks.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill clearly enables network-capable behavior through the external `c0x0` CLI, but the manifest does not declare any tool scope or permissions boundaries. This creates a transparency and governance gap: an agent or reviewer cannot easily determine that the skill will communicate over the network before use, increasing the risk of unintended data egress or misuse.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
test/run.mjs:48