Back to skill

Security audit

clawcall-phone

Security checks for vulnerabilities and agentic risk

Overview

This phone-call skill matches its stated purpose, but it needs Review because it handles real phone calls and sensitive local agent context with weak authorization and serious Windows command-execution risk.

Review carefully before installing. Use it only if you are comfortable sharing phone numbers, call transcripts, schedule/context data, and possible local agent context with ClawCall. Keep the bridge bound to 127.0.0.1, do not expose port 4747, protect CLAWCALL_API_KEY, avoid Windows runtime until shell invocation is fixed, and require explicit approval for third-party calls, recurring calls, callbacks, account recovery, voice changes, and any crypto billing step.

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

T09 · Insecure Skill Coding Practices

Error
Location
listener/clawcall-listener.js:217
Finding
Caller-Controlled Command Injection Through Windows Shell Invocation<![CDATA[ ## Vulnerability Details **File Location**: `listener/clawcall-listener.js:217-225` and `listener/clawcall-listener.js:258-262` **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable Code ```js const { call_sid, message } = res; console.log(`[ClawCall] ↓ call_sid=${call_sid} message="${message}"`); const t0 = Date.now(); const { reply, end_call } = await runAgentTurn(message, call_sid); ``` ```js // On Windows, shell:true is required to resolve openclaw.cmd/.ps1 from PATH. // On Mac/Linux, shell:false is sufficient and avoids an extra shell layer. const proc = spawn( "openclaw", ["agent", "--session-id", callSid, "--message", message, "--json"], { shell: process.platform === "win32", windowsHide: true, stdio: ["pipe", "pipe", "pipe"], } ); ``` ### Technical Analysis The `call_sid` and transcribed `message` values originate from the remote ClawCall API and are passed as command arguments to `child_process.spawn`. On Windows, the code enables `shell: true`. This causes Node.js to construct a command line that is interpreted by the Windows command shell instead of invoking the target executable directly. Node.js explicitly warns against passing unsanitized input to a shell-backed child process. A malicious caller may include Windows shell metacharacters, quoting sequences, variable expansions, or command separators in transcribed speech. If those characters survive transcription and command-line construction, they can alter the intended command and cause additional commands to execute. ### Attack Path 1. An attacker places or participates in a call routed to the listener. 2. The attacker supplies speech that is transcribed into shell-significant characters or syntax. 3. The ClawCall API returns the transcript as `message`. 4. The listener passes `message` to `runAgentTurn`. 5. On Windows, `spawn` invokes OpenClaw through a command shell because `shell: true`. 6. The shell interprets ...[truncated 681 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never use `shell: true` when any argument contains remote or otherwise untrusted data. - Resolve the trusted `openclaw.cmd` or executable path explicitly and invoke it with `execFile` or `spawn` using `shell: false`. - Strictly validate `callSid` against the exact expected identifier format, such as a conservative alphanumeric regular expression and maximum length. - Apply a maximum length and control-character policy to call transcripts before process invocation. - Prefer passing large prompts or messages through standard input rather than command-line arguments. - Run the listener under a dedicated, unprivileged operating-system account. - Add Windows security tests containing characters such as `&`, `|`, `^`, `%`, quotes, parentheses, newlines, and redirection operators. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
bridge/phone-agent-server.js:67
Finding
Model Prompt Passed Through a Windows Command Shell<![CDATA[ ## Vulnerability Details **File Location**: `bridge/phone-agent-server.js:67-88` and `bridge/phone-agent-server.js:159-168` **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable Code ```js function runModel(prompt) { return new Promise((resolve, reject) => { const args = ["infer", "model", "run", MODEL_MODE === "local" ? "--local" : "--gateway", "--json", "--prompt", prompt]; if (MODEL) args.splice(4, 0, "--model", MODEL); if (process.platform === "win32") { const child = spawn("openclaw", args, { shell: true, windowsHide: true, stdio: ["ignore", "pipe", "pipe"], }); ``` ```js const context = await buildPhoneContext(message); const prompt = buildPhonePrompt({ identity: context.identity, user: context.user, contextText: context.contextText, message, }); try { const reply = await runModel(prompt); ``` ### Technical Analysis The generated `prompt` includes the caller-controlled `message`. On Windows, the entire prompt is supplied as a command-line argument to a process created with `shell: true`. Although the input is intended to be an argument to `--prompt`, shell-backed process creation creates a command interpretation boundary. Shell-special characters in the prompt may escape the expected argument context and be interpreted as additional commands or redirections. The prompt can also contain values read from local profile or memory files. Those files therefore constitute an additional untrusted-input source if another process or user can modify the workspace. ### Attack Path 1. An attacker submits a crafted message to `/clawcall/message` or causes a crafted call transcript to reach the bridge. 2. `buildPhonePrompt` embeds the attacker-controlled message into `prompt`. 3. `runModel` places that prompt in the OpenClaw command arguments. 4. On Windows, `spawn` executes the command using a shell. 5. The shell interprets command metacharacters contained in ...[truncated 614 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `shell: true` and invoke a fully resolved, trusted executable using `execFile` or `spawn` with `shell: false`. - Resolve `openclaw.cmd` explicitly on Windows instead of relying on shell command resolution. - Pass model prompts through standard input or a protected temporary file rather than the command line. - Limit prompt and message size and reject control characters that are unnecessary for phone transcripts. - Treat values read from workspace files as untrusted data as well. - Run the bridge under a dedicated, least-privileged account. - Add Windows-specific command-injection regression tests. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
bridge/phone-agent-server.js:191
Finding
Unauthenticated Bridge Endpoint Exposes Private Agent Context<![CDATA[ ## Vulnerability Details **File Location**: `bridge/phone-agent-server.js:191-208` and `bridge/phone-context.js:75-96` **Vulnerability Type**: Missing authentication and sensitive information disclosure **Risk Level**: High ### Vulnerable Code ```js if (req.method === "POST" && req.url === "/clawcall/message") { try { const body = await collectJson(req); const startedAt = Date.now(); const result = await handleCallMessage(body); console.log(`[ClawCallBridge] handled call in ${Date.now() - startedAt}ms`); return sendJson(res, 200, result); } catch (err) { console.error(`[ClawCallBridge] request error: ${err.message}`); return sendJson(res, 500, { response: "I’m having a little trouble right now. Please try again.", end_call: false, }); } } ``` The endpoint can cause private workspace data to be read: ```js function getBasicProfile() { const identityMd = readTextSafe(path.join(WORKSPACE, "IDENTITY.md")); const userMd = readTextSafe(path.join(WORKSPACE, "USER.md")); const identity = extractField(identityMd, "Name") || "jhon"; const user = extractField(userMd, "What to call them") || extractField(userMd, "Name") || "the user"; const timezone = extractField(userMd, "Timezone") || "unknown"; const notes = compact(extractField(userMd, "Notes") || "", 280); return { identity, user, timezone, notes }; } async function buildPhoneContext(message = "") { const profile = getBasicProfile(); const lower = String(message || "").toLowerCase(); const wantsCron = /cron|reminder|schedule|scheduled|job/.test(lower); const wantsTasks = /task|tasks|background|running|pending/.test(lower); const wantsMemory = /remember|preference|prefer|who am i|who is sam/.test(lower); const memoryMd = wantsMemory ? readTextSafe(path.join(WORKSPACE, "MEMORY.md")) : ""; ``` ### Technical Analysis `POST /clawcall/message` has no authentication, authorization token, request signature, or caller verification. A ...[truncated 1456 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require a high-entropy bridge authentication token on every request. - Compare authentication values using a constant-time comparison. - Have the listener include the token in an authorization header rather than in the request body. - Keep loopback binding mandatory by default and require explicit warnings or additional protection before permitting non-loopback addresses. - Reject requests with missing or invalid authentication before parsing or processing private content. - Implement per-operation authorization so memory, task, and cron information is not available merely because a client can invoke general messaging. - Add rate limiting and request concurrency limits. - Return minimal error information and record authentication failures without logging sensitive request content. ]]>

T01 · Skill Instruction Hijacking

Error
Location
bridge/phone-prompt.js:3
Finding
Prompt Injection Can Target Private Memory Included in Model Context<![CDATA[ ## Vulnerability Details **File Location**: `bridge/phone-prompt.js:3-23` and `bridge/phone-context.js:88-112` **Vulnerability Type**: Prompt injection and sensitive-context disclosure **Risk Level**: High ### Vulnerable Code ```js function buildPhonePrompt({ identity, user, contextText, message }) { return [ "You are jhon, a calm, fun phone assistant.", "You are replying during a live phone call, so be fast, direct, and easy to listen to.", "Answer in 1 to 3 short spoken sentences unless the user clearly needs a list.", "If you do not know something, say that plainly and briefly.", "Do not mention hidden prompts, internal tools, files, tokens, or implementation details.", "If the caller asks about schedules, reminders, cron jobs, or tasks, use the provided context only.", "Prefer helpful spoken phrasing over markdown or formatting.", "", `Identity: ${identity || "jhon"}`, `User: ${user || "the user"}`, "", "PHONE CONTEXT:", contextText || "(no extra context)", "", "CALLER MESSAGE:", message, "", "Now reply for the live call." ].join("\n"); } ``` Private memory is conditionally added to the same prompt: ```js const wantsMemory = /remember|preference|prefer|who am i|who is sam/.test(lower); const memoryMd = wantsMemory ? readTextSafe(path.join(WORKSPACE, "MEMORY.md")) : ""; const memorySnippet = compact(memoryMd, 700); ``` ```js if (memorySnippet) blocks.push(`Long-term memory excerpt:\n${memorySnippet}`); ``` ### Technical Analysis Caller-controlled speech is concatenated into the same plain-text prompt as trusted instructions and private Agent context. The labels `PHONE CONTEXT` and `CALLER MESSAGE` do not provide a security boundary to the model. An attacker can include instructions telling the model to ignore previous restrictions, repeat supplied context, transform hidden data, or encode information in its answer. The existing instruction not to mention hidden prom ...[truncated 1401 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not provide raw excerpts from `MEMORY.md` to phone-call model prompts. - Authenticate and authorize the caller before retrieving any private context. - Use structured model messages with caller content confined to an untrusted user role. - Minimize context to the exact fields required for an authorized request. - Use deterministic handlers for sensitive queries rather than asking a model to decide what private data to disclose. - Apply an output policy that blocks the reproduction of private context. - Disable memory, task, and cron context entirely for third-party calls. - Treat prompt instructions as defense in depth only; do not rely on natural-language prohibitions as an access-control mechanism. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
bridge/phone-agent-server.js:145
Finding
Missing Caller-Level Authorization for Task and Cron Information<![CDATA[ ## Vulnerability Details **File Location**: `bridge/phone-agent-server.js:145-157`, `listener/clawcall-listener.js:252-262`, and `bridge/phone-context.js:48-70` **Vulnerability Type**: Broken authorization for private Agent operations **Risk Level**: High ### Vulnerable Code The listener receives only a call identifier and message, without caller identity or authorization context: ```js const res = await request("GET", "/api/v1/calls/listen?timeout=15"); if (res.ok && res.timeout) continue; if (!res.ok || !res.call_sid) { console.error("[ClawCall] Unexpected response:", res); await sleep(3_000); continue; } const { call_sid, message } = res; console.log(`[ClawCall] ↓ call_sid=${call_sid} message="${message}"`); const t0 = Date.now(); const { reply, end_call } = await runAgentTurn(message, call_sid); ``` The bridge discloses task and cron information based only on keywords: ```js if (/cron|reminder|schedule|scheduled|job/.test(lower) && !/meeting|calendar/.test(lower)) { const cronSummary = await getCronSummary(); return { response: `Here are your active cron jobs. ${cronSummary.replace(/\n/g, ' ')}`, end_call: false }; } if (/task|tasks|background|running|pending/.test(lower)) { const taskSummary = await getTaskSummary(); return { response: `Here are your current tasks. ${taskSummary.replace(/\n/g, ' ')}`, end_call: false }; } ``` ### Technical Analysis The authorization decision is based solely on the text of the request. The listener does not forward a verified caller number, owner identity, call type, signed authorization claim, or other principal information to the bridge. Consequently, the bridge cannot distinguish the account owner from another caller, a third-party-call participant, or an unauthenticated local HTTP client. Any request containing task or cron keywords reaches privileged local commands. The documentation states that free-tier calls are restricted to the registered number, but the local code does not en ...[truncated 1083 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require the telephony service to provide a cryptographically signed caller identity and call type. - Forward verified identity claims from the listener to the bridge. - Authorize private intents only when the verified caller is the account owner. - Explicitly deny memory, task, and cron access for third-party and scheduled-call contexts unless separately authorized. - Bind authorization state to the call session and verify it on every turn. - Do not use keywords as authorization decisions. - Return generic responses when the caller lacks permission. - Audit access to private context without recording the sensitive response itself. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
listener/clawcall-listener.js:258
Finding
Sensitive Call Transcripts and Responses Logged in Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `listener/clawcall-listener.js:258-264` **Vulnerability Type**: Sensitive information exposure through logs **Risk Level**: Medium ### Vulnerable Code ```js const { call_sid, message } = res; console.log(`[ClawCall] ↓ call_sid=${call_sid} message="${message}"`); const t0 = Date.now(); const { reply, end_call } = await runAgentTurn(message, call_sid); console.log(`[ClawCall] ↑ reply="${reply.slice(0, 100)}" end_call=${end_call}`); ``` ### Technical Analysis The listener writes complete caller transcripts and the first 100 characters of Agent replies to standard output. Phone conversations may contain personal, medical, financial, authentication, or business-sensitive information. Standard output is frequently persisted by process managers, container platforms, terminal capture, centralized logging services, or support diagnostics. The code does not redact sensitive values, provide a privacy-preserving default, or require explicit debug mode before logging content. The `call_sid` is also logged alongside the transcript, allowing sensitive conversation content to be correlated with a specific call record. ### Attack Path 1. A caller states sensitive information during a call. 2. The telephony service returns the transcript as `message`. 3. The listener prints the complete transcript to standard output. 4. The Agent's reply is also partially logged. 5. Another local user, administrator, log-management operator, compromised collector, or support recipient obtains the logs. 6. The sensitive conversation content is disclosed outside the intended call. ### Impact Assessment The exposed data may include: - Names, phone-related context, and personal preferences. - Account information or authentication material spoken during calls. - Medical, financial, or legal information. - Internal task and schedule information. - Third-party conversation content. The scope depends on log retention, access controls, a ...[truncated 68 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not log transcript or reply content by default. - Log only non-sensitive operational fields such as duration, success status, and a non-reversible event identifier. - Require an explicit debug configuration before content logging is enabled. - Apply structured redaction for credentials, payment data, phone numbers, email addresses, and other sensitive patterns. - Document log retention and deletion requirements. - Protect logs with strict filesystem and centralized logging access controls. - Avoid logging call identifiers together with conversation content. - Add tests ensuring production mode does not emit message or response bodies. ]]>
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description promises a phone integration that can receive calls and also initiate or schedule calls on the user's behalf. The code only provides a lightweight local bridge server that responds to POSTed message payloads with text responses. It includes health checking, basic canned replies, cron/task summaries, and model-backed conversation generation, but there is no code for telephony APIs, dialing, callback workflows, scheduled outbound calls, or calling third parties. While the endpoint may support an external phone system, the implemented capability in this chunk is materially narrower than the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises a telephony skill with real-number calling behavior. This code does something materially different: it gathers contextual data from local markdown files and CLI commands to assemble a phone-context summary. While the context may support a phone agent, this chunk alone does not perform the declared core capabilities. It also accesses local workspace files and OpenClaw task/cron data, which are not reflected in the description. Therefore the description does not accurately represent the behavior of the supplied code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared description promises a telephony skill with real call-related capabilities. The actual code is limited to prompt construction for conversational behavior during a phone interaction. While this may be a supporting component of a phone agent, the provided chunk does not perform the core declared functions and instead serves only as response-formatting/prompting logic. That is a material difference in primary behavior versus the description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code clearly supports one subset of the description: handling inbound calls/messages via ClawCall and routing them to an agent, then returning a reply. However, the declared description promises broader telephony capabilities—callbacks on task completion, scheduled calls, and calling third parties—that are not present in this code chunk. The code only listens for inbound call events (`/api/v1/calls/listen`) and responds on the same call (`/api/v1/calls/respond/{call_sid}`). There is no logic for initiating outbound calls, scheduling, contact management, or task-completion-triggered dialing. Therefore the description materially overstates what this code actually does.

Missing User Warnings

High
Confidence
96% confidence
Finding
The manifest explicitly enables autonomous calls to third parties and scheduled or callback behavior, yet it provides no warning about privacy implications, automated outbound contact, consent requirements, or the handling of personal phone data. Because telephony actions directly affect external people and can expose sensitive information or create harassment, spam, compliance, and trust risks, the missing warnings and constraints materially increase the danger of misuse.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares required environment variables and clearly expects networked/runtime capabilities, but it does not declare an explicit tool scope such as permissions or allowed-tools. That creates an authorization gap where a host may permit broader execution or secret access than reviewers expect, especially since the skill handles an API key, phone numbers, and outbound communications.

External Transmission

Medium
Category
Data Exfiltration
Content
3. Call the registration endpoint:

```
POST https://api.clawcall.online/api/v1/register
Content-Type: application/json

{
Confidence
90% confidence
Finding
The registration flow sends the user's phone number and agent identity to an external service. External transmission is expected for telephony, but it is still security-relevant because it exports personal data and establishes an account with a third party that will handle communications metadata.

External Transmission

Medium
Category
Data Exfiltration
Content
for incoming messages manually:

```
GET https://api.clawcall.online/api/v1/calls/listen?timeout=25
Authorization: Bearer {CLAWCALL_API_KEY}
```
Confidence
88% confidence
Finding
Polling the external listen endpoint transmits the API key and retrieves user call content from a third-party service. Because this endpoint carries both authentication material and potentially sensitive speech transcripts, compromise or misuse could expose private conversations.

External Transmission

Medium
Category
Data Exfiltration
Content
After receiving a message, submit your response:

```
POST https://api.clawcall.online/api/v1/calls/respond/{call_sid}
Authorization: Bearer {CLAWCALL_API_KEY}
Content-Type: application/json
Confidence
88% confidence
Finding
Submitting call responses to the external API sends conversation content off-host and uses bearer-token authentication. In this context, even normal operation can expose sensitive user data if logs, proxies, or the remote service are mishandled.

External Transmission

Medium
Category
Data Exfiltration
Content
When a background task finishes and you need to notify the user by phone:

```
POST https://api.clawcall.online/api/v1/calls/outbound/callback
Authorization: Bearer {CLAWCALL_API_KEY}
Content-Type: application/json
Confidence
88% confidence
Finding
The callback endpoint causes the service to place an outbound phone call containing agent-generated content. This is an external transmission of potentially sensitive task results and can create privacy or social-engineering risk if the message content is not constrained.

External Transmission

Medium
Category
Data Exfiltration
Content
## Scheduling a Recurring Call (Pro tier)

```
POST https://api.clawcall.online/api/v1/calls/schedule
Authorization: Bearer {CLAWCALL_API_KEY}
Content-Type: application/json
Confidence
89% confidence
Finding
Scheduling recurring calls sends task context and timing information to an external provider. That can reveal routines, work patterns, and personal scheduling data, which is particularly sensitive in a phone-assistant context.

External Transmission

Medium
Category
Data Exfiltration
Content
Common patterns: every weekday 8am `"0 8 * * 1-5"` · daily 9am `"0 9 * * *"`.

To cancel: `DELETE https://api.clawcall.online/api/v1/calls/schedule/{id}`

**Requires Pro tier.**
Confidence
84% confidence
Finding
The delete schedule endpoint is another authenticated external action. While less sensitive than message content, misuse could disrupt user workflows by canceling scheduled calls via a bearer token.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill enables autonomous third-party phone calls and relays the conversation back to the agent, but it does not require warnings or consent checks about call recording, disclosure, privacy, or jurisdiction-specific laws. In a telephony context this is materially riskier because the agent may impersonate the user, share personal details, or create compliance exposure without informed consent.

External Transmission

Medium
Category
Data Exfiltration
Content
## Calling a Third Party (Pro tier)

```
POST https://api.clawcall.online/api/v1/calls/outbound/third-party
Authorization: Bearer {CLAWCALL_API_KEY}
Content-Type: application/json
Confidence
93% confidence
Finding
The third-party outbound calling endpoint transmits a target phone number, an objective, and contextual information to an external service so it can autonomously contact another person. In this skill context, that is especially dangerous because it can disclose personal data, enable impersonation, and trigger legal or reputational harm through unsupervised real-world communications.

External Transmission

Medium
Category
Data Exfiltration
Content
## Account & Usage

```
GET https://api.clawcall.online/api/v1/account
Authorization: Bearer {CLAWCALL_API_KEY}
```
Confidence
83% confidence
Finding
Querying the account endpoint sends authentication to a third party and retrieves usage/account data. This is a normal external call, but exposure of account metadata can still aid profiling or abuse if credentials leak.

External Transmission

Medium
Category
Data Exfiltration
Content
## Changing Voice

```
POST https://api.clawcall.online/api/v1/account/voice
Authorization: Bearer {CLAWCALL_API_KEY}
Content-Type: application/json
Confidence
80% confidence
Finding
Changing voice settings is a lower-risk external transmission, but it still relies on bearer-token authenticated remote state change. Unauthorized use could alter user experience or indicate broader credential misuse.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
Including a cryptocurrency billing workflow in a phone-enablement skill expands the attack surface into financial operations that are unrelated to the core task. That creates phishing and misdirection risk, especially because users may be prompted to retrieve a wallet address and send irreversible USDC payments through the same agent workflow.

External Transmission

Medium
Category
Data Exfiltration
Content
**Step 1 — Get payment address and amount:**
```
POST https://api.clawcall.online/api/v1/billing/checkout
Authorization: Bearer {CLAWCALL_API_KEY}
Content-Type: application/json
Confidence
91% confidence
Finding
The billing checkout endpoint initiates a crypto payment workflow with an external service, exposing the user to financial loss if the workflow is spoofed, tampered with, or initiated unexpectedly. Because crypto transfers are typically irreversible, the risk is materially higher than ordinary account-management traffic.

External Transmission

Medium
Category
Data Exfiltration
Content
**Step 3 — Submit transaction signature to confirm:**
```
POST https://api.clawcall.online/api/v1/billing/verify
Authorization: Bearer {CLAWCALL_API_KEY}
Content-Type: application/json
Confidence
90% confidence
Finding
Submitting a transaction signature to verify payment is another sensitive financial transmission to a third party. If abused, it could confirm unintended purchases or facilitate scams around fake upgrade flows.

External Transmission

Medium
Category
Data Exfiltration
Content
Re-register with the same email to rotate the key:

```
POST https://api.clawcall.online/api/v1/register
Content-Type: application/json

{
Confidence
90% confidence
Finding
The recovery flow re-registers using email and phone number to rotate the API key, transmitting sensitive identity data to an external service. If triggered incorrectly or by a malicious prompt, it could rotate credentials unexpectedly and disrupt service or enable account takeover attempts.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code assembles personally sensitive context from IDENTITY.md, USER.md, and optionally MEMORY.md into a phone-facing context blob without any consent check, minimization guard, or indication in this file that the user approved disclosure for a call workflow. In a telephony skill, that context may be spoken over calls or sent to third parties, which increases the risk of privacy leakage beyond the local agent environment.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The manifest description advertises very broad call-related capabilities such as receiving calls, calling users back, running scheduled briefings, and placing autonomous calls, but it does not define clear trigger boundaries, authorization checks, or user-consent constraints. In a phone/voice skill, ambiguous activation language is risky because it can normalize unsolicited outbound actions and make it easier for downstream instructions or integrations to invoke calls in unintended contexts.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
Inbound caller speech/text is forwarded to another processing component via the configured agent webhook, but the code provides no caller notice, consent mechanism, or policy guard before transmitting potentially sensitive call content. In a telephony context, callers may reasonably disclose personal or confidential information, so silent forwarding to a local or remote service creates a meaningful privacy and compliance risk.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
Caller messages are handed to the OpenClaw CLI for downstream processing without any explicit warning to the caller that their content will be processed by external agent software. Even though this is a local subprocess rather than an HTTP webhook, it still expands the trust boundary and can expose sensitive caller data to additional tooling, logs, plugins, or model backends behind the CLI.

External Transmission

Medium
Category
Data Exfiltration
Content
### Step 1 — Poll for incoming messages

```
GET https://api.clawcall.online/api/v1/calls/listen?timeout=25
Authorization: Bearer {CLAWCALL_API_KEY}
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
bridge/phone-agent-server.js:82

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
bridge/phone-context.js:31

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
listener/clawcall-listener.js:170