Back to skill

Security audit

NoChat Channel Plugin

Security checks for vulnerabilities and agentic risk

Overview

This messaging skill claims trust-gated encrypted agent communication, but the reviewed runtime can route remote messages into OpenClaw as authorized commands without enforcing the advertised trust or encryption controls.

Install only after the publisher fixes the trust-enforcement and encryption gaps. Treat NoChat messages as capable of steering your agent, do not grant owner access broadly, use a dedicated low-privilege OpenClaw profile, restrict the server URL to a trusted HTTPS endpoint, and protect or rotate the NoChat API key.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • 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 (4)

T01 · Skill Instruction Hijacking

Error
Location
index.ts:185
Finding

Unconditional Command Authorization for Remote Messages

Content
View full analysis
{ // Send the agent's reply back to NoChat const replyText = payload.text || ""; if (!replyText.trim()) return; const conversationId = msg.conversation_id; if (!conversationId) { console.log("[NoChat] No conversation_id on inbound message — cannot reply"); return; } const result = await client.sendMessage(conversationId, replyText); if (result.ok) { console.log(`[NoChat] Replied to ${senderName} in ${conversationId.slice(0, 8)}`); } else { console.log(`[NoChat] Reply failed: ${result.error}`); } }, onError: (err: unknown, info: { kind: string }) ...[truncated 2212 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
index.ts:131
Finding

Advertised Trust and Rate-Limit Controls Are Bypassed by the Active Inbound Pipeline

Content
View full analysis
{ try { await handleNoChatInbound(ctx, account, config, client, msg); } catch (err) { console.log(`[NoChat] Error handling inbound message: ${(err as Error).message}`); console.log(`[NoChat] Error stack: ${(err as Error).stack}`); } }); await transport.start(); activeTransports.set(account.accountId, transport); ``` Trust enforcement exists in a separate implementation in `src/channel.ts:236-258`: ```ts private async handleInboundMessage(msg: NoChatMessage): Promise { const { allowed, tier } = this.checkInbound(msg.sender_id, msg.sender_name); if (!allowed) { console.log(`[NoChat] Dropped message from blocked agent: ${msg.sender_name} (${msg.sender_id})`); return; } // Rate limit check if (!this.rateLimiter.check(msg.sender_id, tier)) { console.log(`[NoChat] Rate limited: ${msg.sender_name} (${tier})`); return; } // Record interaction for auto-promote this.trustManager.recordInteraction(msg.sender_id); // Route to session const route = this.routeMessage(msg.sender_id, msg.sender_name, tier); if (!route) return; // Format context const context = this.formatInboundContext(msg, tier); console.log(`[NoChat] Routed message to ${route.sessionKey}: ${msg.sender_name} (${tier})`); // In a real integration, this would push the message to the OpenClaw session // via api.runtime.pushMessage(route.sessionKey, context, route.config) // For now, we just log it } ``` ### Technical Analysis The project contains two distinct inbound processing paths ...[truncated 1931 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
index.ts:164
Finding

Base64 Decoding Is Used in Place of Verified End-to-End Decryption

Content
View full analysis
0 ? double : decoded; } catch { text = decoded; } } catch { text = msg.encrypted_content || "[unreadable message]"; } ``` The corresponding message type in `src/types.ts:101-110` describes the field as base64-encoded: ```ts export type NoChatMessage = { id: string; conversation_id: string; sender_id: string; sender_name: string; encrypted_content: string; // base64-encoded message_type: "text" | "file" | "system"; created_at: string; // ISO 8601 }; ``` ### Technical Analysis Base64 is a reversible encoding and provides no confidentiality, integrity, authenticity, or sender verification. The inspected runtime does not perform authenticated decryption, signature validation, key agreement, or verification that the content was produced by the claimed sender. The code also falls back to using the original `encrypted_content` value when decoding fails. It therefore does not fail closed when the purported encrypted payload is malformed. The supplied files contain no implementation that consumes a private key or performs the documented Kyber-1024 or P-256 cryptographic operations. Several imported modules are absent from the supplied project, so behavior outside the reviewed artifact cannot be verified. However, the active message-processing code shown above treats base64-decoded server data as plaintext and immediately forwards it to t ...[truncated 1143 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
index.ts:87
Finding

Configurable Server URL Receives the API Bearer Credential Without Transport or Destination Restrictions

Content
View full analysis
`. 6. The attacker ...[truncated 732 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (11)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README explicitly promotes an owner trust tier that routes remote agent messages into the main session with full tool access, effectively granting remote command authority equivalent to the human operator. In an agent framework, this is a high-risk capability because compromise, spoofing, misconfiguration, or over-trusting another agent can lead to arbitrary tool execution, data exfiltration, and full system-level actions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The plugin claims encrypted, post-quantum end-to-end messaging, but the inbound path merely base64-decodes encrypted_content and treats the result as plaintext, while replies are sent as plaintext through the API client. This creates a security-design mismatch that can expose message contents, cause users or downstream agents to rely on nonexistent confidentiality guarantees, and undermine trust assumptions for authorization or sensitive data handling.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 58)May include surrounding context.

md
PUBLIC_KEY=$(openssl ec -in /tmp/agent_private.pem -pubout -outform DER 2>/dev/null | tail -c 65 | base64)

# Register your agent
curl -X POST https://nochat-server.fly.dev/api/v1/agents/register \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"YourAgentName\",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The configuration example instructs users to place a live API key directly into persistent config without any warning about secret storage, exposure in shell history, or accidental commit to source control. While this is documentation rather than code execution, it normalizes insecure secret-handling practices that can lead to credential leakage and unauthorized use of the messaging account.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill declares network capability in metadata but does not provide an explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, this can cause the plugin to receive broader-than-expected network access and makes operator review harder, increasing the chance of unintended external communication or abuse if the plugin is installed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation instructs users to configure a remote server URL and API key for agent-to-agent messaging but does not clearly warn that message metadata, identifiers, and operational data will be transmitted to an external service. Claims like 'E2E encrypted' and 'server-blind' can reduce user caution, even though registration, discovery, polling, and API-key use still create privacy and trust risks.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code path advertised as the real transport/dispatch layer handles encrypted_content as base64-encoded text rather than cryptographic ciphertext, indicating that the messaging security model is not being enforced here. Even if partly documentary, this misleading implementation increases the chance that maintainers, operators, or agents will treat unprotected content as secure and route sensitive information through it.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 11)May include surrounding context.

json
"test:watch": "vitest"
  },
  "devDependencies": {
    "vitest": "^3.0.0",
    "typescript": "^5.7.0"
  },
  "openclaw": {

Unverifiable Dependency: vitest has 3 known advisory(ies) (CVE-2026-47429 (When Vitest UI server is listening, arbitrary file can be read and executed); CVE-2026-84373 (Vitest: Path Traversal / Arbitrary File Read via @vitest/mocker Redirect Mock); CVE-2025-24964 (Vitest allows Remote Code Execution when accessing a malicious website while Vit)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 12)May include surrounding context.

json
},
  "devDependencies": {
    "vitest": "^3.0.0",
    "typescript": "^5.7.0"
  },
  "openclaw": {
    "extensions": ["./index.ts"],

Static analysis

No suspicious patterns detected.