Back to skill

Security audit

ClawVoice

Security checks for vulnerabilities and agentic risk

Overview

ClawVoice mostly matches its voice-calling purpose, but it handles phone credentials, call transcripts, and agent follow-up events in ways users should review before installing.

Review this before installing, especially if the agent has access to sensitive tools or business accounts. Do not paste provider API keys or auth tokens into chat; use the local setup wizard or environment/config secrets. Expect call transcripts to be stored locally, exported in reports, and optionally sent to Telegram if enabled. Consider disabling transcript notification/export features, setting mainMemoryAccess to none, and avoiding inbound public exposure until the post-call system-event handling is hardened.

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 (2)

T01 · Skill Instruction Hijacking

Error
Location
dist/services/post-call.js:57
Finding

Untrusted Call Transcript Injected into an Actionable System Event

Content
View full analysis
num.length > 4 ? num.slice(0, -4).replace(/./g, "*") + num.slice(-4) : "****"; lines.push(`--- CALL COMPLETED (${dir}) ---`); if (meta?.callerPhone) lines.push(`Phone: ${maskPhone(meta.callerPhone)}`); if (extracted?.callerName) lines.push(`Caller: ${extracted.callerName}${extracted.company ? ` (${extracted.company})` : ""}`); if (extracted?.callbackNumber) lines.push(`Callback: ${maskPhone(extracted.callbackNumber)}`); if (extracted?.reason) lines.push(`Reason: ${extracted.reason}`); lines.push(`Duration: ${this.formatDuration(summary.durationMs)} | Turns: ${transcript.length}`); lines.push(`Outcome: ${summary.outcome}`); // M5: Limit system event transcript to last 5 turns instead of up to 20 if (transcript.length > 0) { lines.push(`\nTranscript (last ${Math.min(transcript.length, 5)} of ${transcript.length} turns):`); for (const entry of transcript.slice(-5)) { const role = entry.speaker === "agent" ? "Agent" : "Caller"; lines.push(`${role}: ${entry.text}`); } } if (recordingUrl) { lines.push ...[truncated 3106 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:50
Finding

Conversational Setup Requests Provider Credentials Through Agent Chat

Content
View full analysis
API Keys** and create a key. It needs **Speech** and **Voice Agent** permissions (or use the default full-access key)." ``` ```md 2. **API key with correct permissions**: "Go to **Developers > API Keys** and create a new key. Set these exact permissions:" | Permission | Level | Required? | |---|---|---| | **ElevenAgents** | **Write** | Yes — this is the Conversational AI endpoint | | Text to Speech | Access | Optional — only if you use `elevenlabsVoiceId` override | | Speech to Speech | No Access | Not used | | Speech to Text | No Access | Not used | | Sound Effects | No Access | Not used | | Audio Isolation | No Access | Not used | | Music Generation | No Access | Not used | | Dubbing | No Access | Not used | | Projects | No Access | Not used | | Audio Native | No Access | Not used | | Voices | Read | Optional — only if you want to list/browse voices via API | | Voice Generation | No Access | Not used | | Forced Alignment | No Access | Not used | | History | No Access | Not used | | Models | No Access | Not used | | Pronunciation Dictionaries | No Access | Not used | | User | No Access | Not used | | Workspace | No Access | Not used | | All other admin permissions | No Access | Not used | **Minimum viable key: ElevenAgents → Write. Everything else can be No Access.** ``` ### Technical Analysis The guided setup tells users to provide Twilio authentication tokens and Telnyx API keys dir ...[truncated 2005 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (58)

YARA rule 'agent_skill_credential_exfiltration_webhook': AI agent skill credential harvesting followed by webhook or external exfiltration [agent_skills]

Critical
Category
YARA Match
Confidence
85% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · dist/index.js (reported line 474)May include surrounding context.

js
ePath = (typeof rawApiConfig?.workspace === "string" ? rawApiConfig.workspace : undefined) ??
        (typeof agentsDefaults?.workspace === "string" ? agentsDefaults.workspace : undefined) ??
        (typeof rawApiConfig?.dataDir === "string" ? rawApiConfig.dataDir : undefined) ??
        (typeof rawApiConfig?.workspacePath === "string" ? rawApiConfig.workspacePath : undefined) ??
        (typeof process.env.OPENCLAW_WORKSPACE === "string" && process.env.OPENCLAW_WORKSPACE.length > 0
            ? process.env.OPENCLAW_WORKSPACE
            : undefined);
    const callService = new clawvoice_1.ClawVoiceService(config, undefined, workspacePath);
    const memoryService = new memory_extraction_1.MemoryExtractionService(config);
    // Wire filesystem-based memory writer for post-call transcript persistence
    if (workspacePath) {
        callService.postCall.setMemoryWriter(async (namespace, key, value) => {
            // M8: Whitelist key characters to prevent path traversal and inject

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code deliberately probes OpenClaw bundled internals and dynamically imports hidden modules to access route-registration functionality not exposed by the public API. This bypasses normal platform boundaries and compatibility guarantees, increasing the risk that the plugin can register unexpected HTTP surfaces or evade expected security controls tied to supported APIs.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The plugin searches internal runtime modules for a system-event enqueue function and then uses it to inject events into active conversations. This is dangerous because it reaches into hidden internals to influence agent context and message flow, potentially enabling unreviewed prompt injection, spoofed notifications, or unauthorized conversation manipulation.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sends call summaries and optional transcript files to Telegram without any visible warning or consent flow in this file. This is a direct third-party disclosure of potentially sensitive call data, and the risk is amplified because destination selection is based on local state rather than an explicit per-user approval step.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The notification sender transmits call summaries and transcript files to a Telegram chat, which is an external dissemination of sensitive data outside the local agent environment. Once sent, the operator loses control over downstream storage, forwarding, and retention on the third-party platform.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · dist/prompts/personalities.js (reported line 344)May include surrounding context.

js
*/
function personalizePrompt(prompt, ownerName) {
    const name = ownerName?.trim() || "the user";
    return prompt.replace(/\{\{OWNER_NAME\}\}/g, name);
}

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The campaign report tool reads stored call records and exports a CSV containing transcripts and extracted personal details, then saves that file to disk, but its interface does not clearly warn users that sensitive conversational data will be exported and persisted locally. Because this skill handles voice calls and SMS-related workflows, the exported data may include names, companies, phone context, and full conversation content, creating a significant confidentiality and privacy risk.

Content

No source excerpt is available for this finding.

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
97% confidence
Finding

The lockfile pins the skill to ws 8.19.0, and the provided advisory data indicates this exact version is affected by an uninitialized memory disclosure and a memory-exhaustion denial of service. Because this is a bundled runtime dependency, any skill functionality that opens WebSocket connections could expose memory contents or be crashed by a malicious peer through crafted traffic.

Content

No source excerpt is available for this finding.

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
98% confidence
Finding

The package declares ws 8.19.0, which is identified as having advisories for uninitialized memory disclosure and memory-exhaustion denial of service. In a voice-calling plugin, WebSocket handling is likely exposed to network-originated traffic, making crashes, resource exhaustion, or unintended data exposure materially more dangerous than in an offline-only tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly instructs the user to provide highly sensitive secrets such as a Twilio Account SID and Auth Token directly in conversation. In an agent setting, conversational channels may be logged, retained, or exposed to other tools, so collecting credentials this way creates a real risk of secret disclosure and downstream account compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The Telnyx setup flow asks the user to provide an API key and connection details without any warning about secret handling. Because the skill itself says voice sessions are untrusted input channels, requesting secrets through the assistant is especially unsafe and could leak credentials through logs, transcripts, or unintended model/tool exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The Deepgram setup section requests a sensitive API key and then gives configuration commands, but it never warns the user not to disclose the key in the chat. This can lead to credential exposure in stored transcripts or debugging systems, enabling unauthorized use of the voice provider account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The ElevenLabs section asks for an API key and agent identifier while discussing detailed permission scopes, which may encourage users to paste a working privileged key into the chat. Even if scope is minimized, exposure of an ElevenAgents write-capable key can permit unauthorized agent manipulation or service abuse if captured from logs or transcripts.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · dist/cli.js (reported line 118)May include surrounding context.

js
// Auto-detect ngrok tunnel if running
        let detectedTunnelUrl = "";
        try {
            const resp = await globalThis.fetch("http://localhost:4040/api/tunnels", { signal: AbortSignal.timeout(2000) });
            const data = await resp.json();
            const httpsTunnel = data.tunnels?.find((t) => t.proto === "https");
            if (httpsTunnel?.public_url) {

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · dist/cli.js (reported line 449)May include surrounding context.

js
// Auto-detect ngrok tunnel if running
        let detectedTunnelUrl = "";
        try {
            const resp = await globalThis.fetch("http://localhost:4040/api/tunnels", { signal: AbortSignal.timeout(2000) });
            const data = await resp.json();
            const httpsTunnel = data.tunnels?.find((t) => t.proto === "https");
            if (httpsTunnel?.public_url) {

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

With no manifest available to justify capabilities, this setup-oriented CLI does more than local configuration: it uses provided Twilio credentials to query the account and POST updates that change the phone number's voice and SMS webhook configuration. Modifying a third-party account is a materially stronger capability than merely collecting setup values or printing instructions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The clawvoice call command initiates a real outbound phone call through callService.startCall(...). While the command description states it initiates an outbound phone call, the code does not present any final confirmation or caution before placing the call, which is a safety-relevant external action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The clawvoice sms command performs a real outbound text send via callService.sendText(...), which can affect user data, incur cost, and contact third parties. Although usage and validation are shown, there is no confirmation prompt or explicit safety disclosure immediately before the send operation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The clawvoice expose command goes beyond diagnostics or local profile management by actively changing Tailscale exposure state, potentially making a local media endpoint reachable over the network. Without manifest context declaring network exposure or system reconfiguration, this is an unjustified capability for an unknown-purpose skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The default configuration sets deepgramVoice to aura-asteria-en, which hard-codes an English voice locale. This is a natural-language policy concern because the file does not indicate any user choice, opt-in, or documented justification for forcing English as the default language/locale.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The plugin writes full post-call records and a human-readable latest-summary markdown file into the workspace, making potentially sensitive conversation content broadly available to the agent environment. Even if intended for productivity, this expands data exposure and can leak private details to other tools, prompts, or plugins with workspace access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The plugin persists post-call summaries and transcript content into workspace files without any visible disclosure, consent, or retention controls in this file. Because the workspace is agent-accessible, sensitive spoken content may be retained longer than expected and reused by other components or future sessions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The plugin adds outbound Telegram delivery of call summaries and transcript attachments, which is a separate data-export capability beyond core telephony handling. This creates an external exfiltration path for sensitive call content and metadata, especially because this file shows no consent gate, minimization, or explicit disclosure before sending data to a chat ID resolved from local state.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This fetch to the Telegram Bot API is an external transmission sink carrying call-derived notification content. External transmission is risky here because the payload can include sensitive summaries and attached transcript files, making it more than a routine network call.

Content

Scanner excerpt · dist/index.js (reported line 545)May include surrounding context.

js
catch { /* ignore — file may not exist */ }
        if (ownerChatId) {
            callService.postCall.setNotificationSender(async (notification) => {
                const botUrl = `https://api.telegram.org/bot${botToken}`;
                try {
                    // Send the summary message
                    const summaryResp = await globalThis.fetch(`${botUrl}/sendMessage`, {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The shared prompt block explicitly instructs the agent to generate an internal post-call summary containing caller identity, purpose, urgency, and follow-up details, including potentially sensitive topics. In a voice-call context this creates a real privacy and compliance risk when no companion disclosure, consent, data-minimization rule, or retention boundary is enforced in this file.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal, suspicious.prompt_injection_instructions

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
dist/cli.js:1047

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
dist/index.js:474

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
dist/services/clawvoice.js:102

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
README.md:169