Back to skill

Security audit

Voice Assistant

Security checks for vulnerabilities and agentic risk

Overview

This looks like a real voice assistant, but it needs Review because it handles live speech and credentials with weak privacy and endpoint safeguards.

Install only if you are comfortable with an always-on local voice assistant. Keep the gateway on the default local address unless you have a trusted secure endpoint, treat the .env tokens as secrets, avoid speaking sensitive information while default logging is enabled, and prefer pinned dependencies or an isolated environment before running it.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unpinned Third-Party Dependencies Allow Unreviewed Package Code

Content
View full analysis
=3.0 faster-whisper>=1.0 elevenlabs>=2.0 av sounddevice numpy websockets>=12.0 pystray>=0.19 Pillow pynput>=1.7 python-dotenv>=1.0 ``` The documented installation procedure executes these dependency declarations: ```bash python -m venv venv venv\Scripts\pip install -r requirements.txt ``` ### Technical Analysis Every declared dependency is either completely unpinned or constrained only by a minimum version. No lock file, package hashes, index restrictions, or integrity-verification mechanism is provided. Consequently, the code installed by the documented command can change without any modification to the audited project. A future release satisfying one of the version constraints will be accepted automatically. Packages such as `sounddevice`, `pynput`, `pystray`, and the speech-service SDKs execute native or Python code with the current user's privileges. This is a supply-chain weakness rather than evidence that any currently declared package is malicious. ### Attack Path 1. An attacker compromises a maintainer account, package release process, dependency distribution infrastructure, or the package index configured on the user's system. 2. The attacker publishes a malicious version satisfying the open-ended constraint, such as a version greater than or equal to the declared minimum. 3. A user follows the documented setup procedure and runs `pip install -r requirements.txt`. 4. Pip resolves the malicious release because no exact version or trusted hash is required. 5. Malicious package code executes during installation or when imported by the assistant. 6. The package inherits the privileges and data access of the user running the application. ### Impact Assessment Successful exploitation could ...[truncated 626 chars]
Remediation
View remediation
python-dotenv== ``` 2. Generate a fully resolved lock file that includes transitive dependencies. 3. Record cryptographic hashes and install with hash enforcement: ```bash python -m pip install --require-hashes -r requirements.lock ``` 4. Use a trusted, explicitly configured package index and disable unintended extra indexes. 5. Review package provenance, maintainers, release history, and native binary distribution before approving updates. 6. Run dependency vulnerability and malware scans in CI. 7. Update dependencies through a controlled process that reviews code and release changes before regenerating hashes. 8. Install and run the application as a non-administrative user in an isolated virtual environment. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/src/gateway_client.py:27
Finding

Gateway Credentials and Transcripts Can Be Sent over Insecure or Attacker-Controlled WebSocket Endpoints

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/src/assistant.py:94
Finding

Sensitive Conversation Content Is Logged at INFO Level

Content
View full analysis
str: """Transcribe int16 audio array to text using faster-whisper.""" model = _get_whisper() audio_float = audio.astype(np.float32) / 32768.0 segments, info = model.transcribe(audio_float, beam_size=1, language="en") text = " ".join(seg.text.strip() for seg in segments).strip() log.info("Transcribed (%s): %s", f"{info.duration:.1f}s", text) return text ``` ### Technical Analysis Conversation content is emitted at `INFO` level, which is enabled by default in `assistant.py`. The user transcript is logged twice, and assistant output is partially logged. Although the current logging configuration writes to the process output rather than explicitly creating a file, console output may be retained by: - Terminal capture or redirection. - Process supervisors. - Debugging and support b ...[truncated 1524 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (33)

YARA rule 'keylogger_indicators': Keylogger functionality in scripts or source code [malware]

High
Category
YARA Match
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/src/assistant.py (reported line 147)May include surrounding context.

python
rget=_speak_then_listen, daemon=True).start()
        else:
            _in_conversation = False
            log.warning("Empty response from gateway")

    except Exception as e:
        stop_thinking()
        _in_conversation = False
        log.error("Error communicating with gateway: %s", e)


def _setup_hotkey():
    """Register global hotkey as alternative to wake word."""
    try:
        from pynput.keyboard import GlobalHotKeys

        parts = config.HOTKEY.split("+")
        combo_parts = []
        for p in parts:
            p = p.strip().lower()
            if p in ("ctrl", "control"):
                combo_parts.append("<ctrl>")
            elif p in ("shift",):
                combo_parts.append("<shift>")
            elif p in ("alt",):
                combo_parts.append("<alt>")
            elif p in ("cmd", "win", "super"):
                combo_parts.append("<cmd>")
            else:
                combo_parts.append(p)
        combo = "+".join(combo_parts)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
"""Configuration loader — reads settings from .env file."""

import os
from pathlib import Path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
"""Configuration loader — reads settings from .env file."""

import os
from pathlib import Path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/architecture.md (reported line 11)May include surrounding context.

md
"""Configuration loader — reads settings from .env file."""

import os
from pathlib import Path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/src/audio_pipeline.py (reported line 65)May include surrounding context.

python
"""Configuration loader — reads settings from .env file."""

import os
from pathlib import Path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/src/config.py (reported line 1)May include surrounding context.

python
"""Configuration loader — reads settings from .env file."""

import os
from pathlib import Path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/src/config.py (reported line 7)May include surrounding context.

python
"""Configuration loader — reads settings from .env file."""

import os
from pathlib import Path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/generate_chime_sounds.py (reported line 58)May include surrounding context.

python
# Load .env from project root
_project_root = Path(__file__).resolve().parent.parent
load_dotenv(_project_root / ".env")

# OpenClaw Gateway
GATEWAY_URL = os.getenv("GATEWAY_URL", "ws://127.0.0.1:18789")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/generate_thinking_sounds.py (reported line 58)May include surrounding context.

python
# Load .env from project root
_project_root = Path(__file__).resolve().parent.parent
load_dotenv(_project_root / ".env")

# OpenClaw Gateway
GATEWAY_URL = os.getenv("GATEWAY_URL", "ws://127.0.0.1:18789")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/src/assistant.py (reported line 235)May include surrounding context.

python
# Load .env from project root
_project_root = Path(__file__).resolve().parent.parent
load_dotenv(_project_root / ".env")

# OpenClaw Gateway
GATEWAY_URL = os.getenv("GATEWAY_URL", "ws://127.0.0.1:18789")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/src/config.py (reported line 9)May include surrounding context.

python
# Load .env from project root
_project_root = Path(__file__).resolve().parent.parent
load_dotenv(_project_root / ".env")

# OpenClaw Gateway
GATEWAY_URL = os.getenv("GATEWAY_URL", "ws://127.0.0.1:18789")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents access to environment secrets and local file creation/modification (.env creation, venv/dependency installation) but does not declare any explicit tool scope or permissions metadata. This creates a transparency and policy gap: users and hosting platforms cannot clearly evaluate or constrain what the skill needs before use, increasing the chance of over-privileged execution or unsafe deployment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill description and quick-start flow emphasize voice convenience but do not prominently warn that it continuously listens for a wake word and automatically performs follow-up recording after responses. This is a privacy-relevant omission because users may deploy always-on microphone software without fully understanding that ambient speech can be captured beyond a single push-to-talk interaction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The architecture explicitly describes a microphone that is continuously available for wake-word monitoring, records follow-up speech, transcribes it, and forwards text to another component, but it does not mention any user-facing consent, recording indicator, retention policy, or privacy notice. In a voice-assistant skill, this omission increases the risk of covert or unexpected capture of nearby speech and can lead to privacy harm even if the implementation is intended for local use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The assistant sends transcribed microphone input to a gateway service without any explicit consent notice, transmission indicator, or user-facing privacy warning in this code path. Because voice input may contain sensitive personal or credential information, silent forwarding increases privacy and data exposure risk even if the gateway is expected functionality.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The transcription call hard-codes language="en", which enforces a specific language regardless of the user's actual locale or preference. This is a natural-language policy concern because the file provides no opt-in, fallback, or justification for restricting recognition to English.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code sends a credential-bearing authentication payload over the network by placing GATEWAY_TOKEN into the WebSocket connect request. Although the code logs the connection target, it does not provide any user-facing warning, confirmation, or explanatory comment/docstring disclosing that a sensitive token will be transmitted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code sends arbitrary spoken-response text to ElevenLabs, a third-party cloud TTS provider, without any in-code consent flow, disclosure, or data-minimization guardrails. In a voice assistant context, responses may contain sensitive user data, making this a real privacy and data-exposure issue even if the feature is intentional.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Using 'pvporcupine>=3.0' permits any future major/minor release above 3.0, which weakens reproducibility and increases supply-chain exposure if upstream publishes a bad release. There is no evidence of active exploitation here, but open-ended version ranges are a recognized dependency hygiene risk.

Content

Scanner excerpt · scripts/requirements.txt (reported line 1)May include surrounding context.

text
pvporcupine>=3.0
faster-whisper>=1.0
elevenlabs>=2.0
av

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Using 'faster-whisper>=1.0' leaves the installed version unconstrained above the minimum, so different users may get different code and security posture. For an audio-processing assistant, that can affect native/transitive components and make incident response harder.

Content

Scanner excerpt · scripts/requirements.txt (reported line 2)May include surrounding context.

text
pvporcupine>=3.0
faster-whisper>=1.0
elevenlabs>=2.0
av
sounddevice

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Using 'elevenlabs>=2.0' allows future upstream releases without review, which is a supply-chain and stability concern. While this is not direct proof of compromise, dependency drift can introduce vulnerable API clients or unexpected behavior in a network-connected voice assistant.

Content

Scanner excerpt · scripts/requirements.txt (reported line 3)May include surrounding context.

text
pvporcupine>=3.0
faster-whisper>=1.0
elevenlabs>=2.0
av
sounddevice
numpy

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency 'av' is unpinned, so installations may resolve to different versions over time, reducing build reproducibility and increasing supply-chain risk if a newly published version is vulnerable or malicious. In a voice assistant context that processes media/audio, this matters because codec/parsing libraries are historically exposed to malformed-input issues.

Content

Scanner excerpt · scripts/requirements.txt (reported line 4)May include surrounding context.

text
pvporcupine>=3.0
faster-whisper>=1.0
elevenlabs>=2.0
av
sounddevice
numpy
websockets>=12.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency 'sounddevice' is unpinned, allowing non-deterministic installs and making it hard to verify whether deployed environments use a secure version. Although this is usually operational rather than immediately exploitable, audio-device libraries can still inherit vulnerabilities through dependency drift.

Content

Scanner excerpt · scripts/requirements.txt (reported line 5)May include surrounding context.

text
faster-whisper>=1.0
elevenlabs>=2.0
av
sounddevice
numpy
websockets>=12.0
pystray>=0.19

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency 'numpy' is not pinned to an exact version, so the installed package may vary across environments and may include versions with known advisories. This is more relevant here because the static analysis already indicates multiple historical advisories, but the manifest does not let reviewers determine whether affected versions are excluded.

Content

Scanner excerpt · scripts/requirements.txt (reported line 6)May include surrounding context.

text
elevenlabs>=2.0
av
sounddevice
numpy
websockets>=12.0
pystray>=0.19
Pillow

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The manifest does not pin 'numpy', and the package has multiple known historical advisories, so reviewers cannot verify from this file whether deployed versions are affected or patched. This is a real supply-chain risk, though the manifest alone does not prove an exploitable vulnerable version is currently installed.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.