Back to skill

Security audit

WebChat Voice GUI

Security checks for vulnerabilities and agentic risk

Overview

This skill provides the advertised local voice-input feature, but it also installs a persistent startup hook that keeps rewriting the OpenClaw Control UI with browser JavaScript from a mutable workspace file.

Install only if you are comfortable with a skill patching your local OpenClaw Control UI and installing a startup hook that re-applies JavaScript after updates. Review who can modify ~/.openclaw/workspace/voice-input/voice-input.js, keep the workspace protected, and consider disabling or uninstalling the hook if you do not need update-survival behavior.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T06 · System Persistence

Error
Location
scripts/deploy.sh:79
Finding

Persistent Gateway Startup Hook Promotes User-Writable JavaScript into the Control UI

Content
View full analysis
{ if (event.type !== "gateway" || event.action !== "startup") return; // SECURITY: execFileSync with array args — no shell interpolation. // Script path is derived from __dirname (relative to this file), not user input. const script = join(__dirname, "inject.sh"); try { execFileSync("bash", [script], { timeout: 10_000, ``` #### `hooks/inject.sh:27-34` ```bash cp -f "$SRC" "$ASSET_DIR/voice-input.js" if ! grep -q "$MARKER" "$INDEX" 2>/dev/null; then # SECURITY: sed uses only hardcoded strings — no variable interpolation. sed -i 's|| \n |' "$INDEX" echo "[voice-input-inject] Injected into $INDEX" else echo "[voice-input-inject] Already present in $INDEX" ``` ### Technical Analysis Deployment creates a persistent OpenClaw gateway startup hook under `~/.openclaw/hooks/voice-input-inject`. Whenever the gateway emits a startup event, `handler.ts` invokes `inject.sh` through Bash. The script then copies `~/.openclaw/workspace/voice-input/voice-input.js` into the trusted OpenClaw Control UI asset directory and ensures that `index.html` loads it. Although `execFileSync` avoids shell-argument injection, it does not address the trust-boundary problem. The startup hook treats a workspace file as truste ...[truncated 2157 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented primarily as a voice-input UI enhancement, but it also persistently injects JavaScript into the Control UI and installs a gateway startup hook that re-applies the patch after updates. Persistent code injection and startup execution materially increase risk because they create a durable mechanism to modify trusted UI code and can be repurposed for credential theft, UI tampering, or broader compromise if the injected asset or hook is changed.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/uninstall.sh (reported line 30)May include surrounding context.

sh
# 2) Remove voice-input.js from Control UI and undo index.html injection
echo "[2/3] Reverting Control UI..."
if [[ -f "$ASSET_DIR/voice-input.js" ]]; then
  rm -f "$ASSET_DIR/voice-input.js"
  echo "      removed: voice-input.js asset"
fi

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/uninstall.sh (reported line 43)May include surrounding context.

sh
# 3) Remove workspace runtime files (voice-input.js, i18n.json)
echo "[3/3] Removing workspace runtime files..."
rm -f "$VOICE_DIR/voice-input.js" "$VOICE_DIR/i18n.json"
rmdir "$VOICE_DIR" 2>/dev/null && echo "      removed: $VOICE_DIR" || true

# Restart gateway

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares shell and network-relevant behavior in its metadata and description, but does not define an explicit tool scope such as permissions or allowed-tools. This weakens reviewability and enforcement because a skill that modifies installed UI files, installs a persistent startup hook, and depends on local network services should clearly declare the operational capabilities it needs.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
- VOICE_LANG (optional, default: auto — prompts interactively if not set)
  persistence:
    - "Gateway startup hook: voice-input-inject (re-injects JS after updates)"
  privileges: user-level only, no root/sudo required
  dependencies:
    - faster-whisper transcription service on port 18790
---

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file includes a dedicated Chinese locale block alongside English and German, but the content itself does not show any mechanism for user opt-in or locale selection policy. Under the language/locale policy rule, hard-coded locale behavior can be problematic unless the skill explicitly offers a choice or documents why the locale is constrained.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code captures microphone audio and posts it to a transcription endpoint via fetch, but the UI shown here does not provide a clear privacy disclosure about where audio is sent, what service processes it, or what trust boundary applies. Although browser mic permission is required and the metadata claims 'local' transcription, the implementation may send audio to same-origin /transcribe or localhost, so users can be misled into sharing sensitive speech without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

In continuous mode, transcribed text is automatically sent after a short 2-second review window unless the user focuses or clicks the textarea. This can cause unintended transmission of sensitive or erroneous speech-derived content into the chat workflow, especially because speech recognition errors, ambient audio, or stop-keyword misses may result in content being sent without explicit confirmation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code imports child_process and invokes bash to run inject.sh on startup. Spawning an external process is a privileged operational capability that is not obviously required for microphone capture, local STT, VU metering, or keyboard shortcuts as described in the manifest, aside from a vague note about a gateway hook.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest focuses on microphone UI, recording, local transcription, and keyboard controls, with only a brief mention of a 'gateway hook for update safety.' In this file, the implemented behavior is launching an external bash script during gateway startup to modify the Control UI, which is a materially different operational capability than the user-facing voice features described.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest primarily describes UI voice-input behavior and mentions an 'update safety' gateway hook, but this script performs direct file-system modification of the Control UI distribution by copying a script into assets and rewriting index.html. That install-time patching behavior is not clearly conveyed by the main description and is broader than merely providing microphone/transcription functionality.

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 · references/troubleshooting.md (reported line 12)May include surrounding context.

Checks:

bash
systemctl --user status openclaw-transcribe.service
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:18790/transcribe -X POST -H 'Content-Type: application/octet-stream' --data-binary 'x'

If this is down/missing, voice input will not produce text.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Checking and interacting with systemd user services, plus restarting the OpenClaw gateway, is a host-level operational capability not inherently required just to provide browser microphone input and local transcription UI. While adjacent to deployment, it expands the skill's effective control over local runtime services beyond the core voice-button purpose described in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script copies assets into the workspace and Control UI directories, patches JavaScript with sed, modifies index.html, and installs hook files, all without an explicit warning or confirmation to the user. Silent modification of application files and startup behavior is risky because users may not realize they are granting persistent code execution and altering the UI's trusted contents.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The deploy script installs a persistent gateway hook under the user's OpenClaw hooks directory, which causes code from this skill to survive normal UI updates and continue executing later. Persistence mechanisms are security-relevant because they expand the trust boundary from a one-time UI asset copy to ongoing code execution, and the script does not present explicit consent or integrity checks for the hook contents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script restarts the OpenClaw gateway automatically and suppresses output, which can disrupt active sessions and applies newly installed hook behavior immediately without the user noticing. While low severity on its own, automatic service restarts reduce user awareness and compound the persistence risk introduced earlier in the script.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
hooks/handler.ts:14