Back to skill

Security audit

Video Chat With Me

Security checks for vulnerabilities and agentic risk

Overview

This is a real video-chat skill, but it needs review because it exposes an unauthenticated network bridge to the user's main OpenClaw agent and installs persistent background service behavior.

Review before installing. Use it only if you are comfortable sending audio to Groq, TTS text to Microsoft, and camera frames/text through your OpenClaw gateway to the configured model. Before use, restrict the server to localhost or add authentication, avoid exposing it on LAN/Tailscale without pairing, remove or explicitly opt into launchd persistence, store the Groq key with restrictive permissions or a keychain, and prefer an isolated least-privileged OpenClaw agent instead of the main agent.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (5)

T06 · System Persistence

Error
Location
scripts/setup.sh:155
Finding

Unconditional Persistent Launch Agent Installation

Content
View full analysis
/dev/null || true launchctl unload "$PLIST" 2>/dev/null || true cat > "$PLIST" << PLISTEOF Label ${PLIST_LABEL} ProgramArguments $(which python3) ${SCRIPTS_DIR}/server.py WorkingDirectory ${SKILL_DIR} RunAtLoad KeepAlive SuccessfulExit ThrottleInterval 5 StandardOutPath /tmp/videochat-withme.log StandardErrorPath /tmp/videochat-withme.log EnvironmentVariables AGENT_NAME ${AGENT_NAME} USER_NAME ${USER_NAME} PORT ${PORT} PATH /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin PLISTEOF if [ -n "$SSL_CERT" ] && [ -n "$SSL_KEY" ]; then cat >> "$PLIST" << SSLEOF SSL_CERT ${SSL_CERT} SSL_KEY ${SSL_KEY} SSLEOF fi cat >> "$PLIST" << ENDEOF ENDEOF launchctl load "$PLIST" ``` ### Technical Analysis The setup process always creates and loads a per-user launch agent. `RunAtLoad` causes the service to start whenever the user logs in, while ...[truncated 1628 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/server.py:101
Finding

Unauthenticated Network Bridge to the Privileged Main OpenClaw Agent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/server.py:101
Finding

Unbounded Sensitive Upload Storage Without Cleanup

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:37
Finding

Unpinned Global Dependency Installation During Setup and Startup

Content
View full analysis
/dev/null 2>&1; then echo " Installing:$MISSING" brew install $MISSING else echo "❌ Missing:$MISSING" echo " Install with: brew install$MISSING" exit 1 fi fi echo " ✅ python3 $(python3 --version 2>&1 | awk '{print $2}')" echo " ✅ ffmpeg" # 2. Install Python deps echo "" echo "📦 Installing Python dependencies..." pip3 install --break-system-packages -q fastapi uvicorn python-multipart httpx edge-tts 2>/dev/null || \ pip3 install -q fastapi uvicorn python-multipart httpx edge-tts echo " ✅ Done" ``` The same unsafe Python installation behavior also occurs during ordinary startup in `scripts/start.sh:19-23`: ```bash pip3 install --break-system-packages -q fastapi uvicorn python-multipart httpx edge-tts 2>/dev/null || \ pip3 install -q fastapi uvicorn python-multipart httpx edge-tts exec python3 server.py ``` ### Technical Analysis The scripts install packages without pinned versions or integrity hashes. Dependency resolution therefore depends on mutable repository state at execution time, making the reviewed source insufficient to determine the exact code that will run. The `--break-system-packages` option deliberately bypasses protections intended to prevent global Python-environment modification. Moreover, `start.sh` performs package installation as part of ordinary startup, so a routine attempt to launch the service can unexpectedly modify the user's environment and execute package installation logic. The audit did not identify a confirmed malicious package or typosquatted dependency. The issue is the unsafe supply-chain and environment-management practice itself. ### Attack Path 1. A user executes `setup.sh` or invokes `start.sh` when no launchd service is runni ...[truncated 943 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/call.sh:6
Finding

AppleScript Injection Through Environment-Controlled Agent Name

Content
View full analysis
&1) || true ``` ### Technical Analysis `AGENT_NAME` is inserted directly into AppleScript source enclosed by double quotes. Shell expansion occurs before `osascript` parses the script. An attacker who can influence this environment variable can include quotes, statement separators, and AppleScript syntax that terminate the intended string and introduce additional statements. This is a source-code injection flaw rather than ordinary display-string handling. Shell quoting around the multiline argument does not make the expanded value safe for the AppleScript parser. The setup script stores an agent name in the launch-agent environment, while `call.sh` independently accepts `AGENT_NAME` from its invocation environment. Exploitation therefore requires control over the environment or invocation context used for `call.sh`; the unauthenticated HTTP endpoint does not directly set this variable. ### Attack Path 1. An attacker gains the ability to influence the `AGENT_NAME` environment variable used when `call.sh` is invoked, such as through an unsafe wrapper, automation, or compromised calling context. 2. The attacker supplies a value containing a closing quote and additional AppleScript statements. 3. Shell expansion inserts that value into the string passed to `osascript -e`. 4. `osascript` parses the injected statements as executable AppleScript rather than dialog text. 5. Injected AppleScript can invoke facilities such as `do shell script`, executing commands under the account that ...[truncated 513 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
Findings (47)

Tainted flow: 'text' from httpx.post (line 247, network input) → subprocess.run (code execution)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

External input (network, user) flows to a code execution sink. This enables remote code execution or command injection.

Content

Scanner excerpt · scripts/server.py (reported line 269)May include surrounding context.

python
for attempt in range(1, max_retries + 1):
        try:
            logger.info("TTS attempt %d/%d for %d chars", attempt, max_retries, len(text))
            result = subprocess.run(
                [
                    "edge-tts",
                    "--voice", voice,

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented behavior presents a full real-time video chat pipeline, but the operational instructions mainly implement a launcher that checks a local service, runs setup, and opens a browser or notification flow. This mismatch is dangerous because users and reviewers may consent to one set of behaviors while the skill actually performs different local automation and setup actions, reducing informed consent and masking risk.

Content

No source excerpt is available for this finding.

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

This code forwards transcripts and optional camera frames into the main OpenClaw agent with persistent session identity and full memory/personality. In the stated skill context, that means highly sensitive real-time data can be propagated into a broader agent environment and possibly to a configured cloud LLM, increasing exfiltration and over-collection risk beyond a narrow video-chat function.

Content

Scanner excerpt · scripts/server.py (reported line 193)May include surrounding context.

python
async def get_openclaw_reply(transcript: str, image_b64: str | None, language: str = "zh") -> str:
    """
    Send message to OpenClaw chatCompletions API.
    Routes to the main agent with full memory and personality.
    The 'user' field creates a stable session for videochat conversations.
    """

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script prompts for a Groq API key and writes it to ~/.openclaw/secrets/groq_api_key.txt without clearly disclosing credential-at-rest risks or setting restrictive permissions. Storing cloud credentials on disk can expose them to other local processes, backups, or accidental leakage, and this skill routes audio to a cloud STT provider so the credential has real external-service value.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill instructs the agent to perform shell commands, read and write files under ~/.openclaw, access secrets, and make network requests, yet it declares no explicit tool scope or permission boundaries. This creates an authorization gap where an agent may execute sensitive operations without clear least-privilege constraints or user-visible approval.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Trigger phrases like 'call me', 'voice call', and common Chinese conversational phrases are broad enough to match ordinary dialogue, increasing the chance of unintended activation. In this skill's context, accidental invocation is more serious because activation can lead to setup actions, network exposure, browser opening, or persistent service installation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The setup guidance says it 'handles everything' but does not prominently warn at the point of execution that running setup may install a persistent launchd service. Users may approve the command without understanding that it creates background persistence, which has meaningful security and privacy implications for a camera/microphone-related skill.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The instructions persist an API key to a plaintext file under ~/.openclaw/secrets, creating long-lived local credential storage that could be exposed through weak filesystem permissions, backups, or other local compromise. While common in developer tooling, it still increases the attack surface by retaining a reusable secret beyond the immediate session.

Content

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

  1. Get a free key at: https://console.groq.com/keys
  2. Save it:
    bash
    mkdir -p ~/.openclaw/secrets
    echo "your-key-here" > ~/.openclaw/secrets/groq_api_key.txt
    
    Or set env var: export GROQ_API_KEY="your-key-here"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code captures camera frames with canvas.toBlob() and attaches the image to the /api/chat request whenever the camera is enabled, but there is no explicit warning at send time that snapshots are being transmitted to the backend and potentially onward to an LLM provider. Because camera imagery is highly sensitive and the skill metadata says frames may leave the machine, the lack of clear disclosure materially increases privacy risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The page records microphone input and automatically uploads it to /api/chat, but the UI only indicates recording state and does not clearly warn that captured speech will be transmitted off-device and may be retained or processed by backend/cloud services. In a voice/video chat skill, users may assume local processing, so the omission creates a real privacy/security issue through inadequate informed consent rather than a code-execution flaw.

Content

No source excerpt is available for this finding.

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

Scanner excerpt · assets/index.html (reported line 1688)May include surrounding context.

html
function unlockAudio() {
    if (audioUnlocked) return;
    audioUnlocked = true; // Set immediately to prevent re-entry
    const silentAudio = new Audio('data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4Ljc2LjEwMAAAAAAAAAAAAAAA//tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAABhgC7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//////////////////////////////////////////////////////////////////8AAAAATGF2YzU4LjEzAAAAAAAAAAAAAAAAJAAAAAAAAAAAAYYoRBqpAAAAAAD/+1DEAAAHAAGf9AAAIiWJs/80YAAAABBBP/k/JCCBnn5QEDBh+sCDv/KAgb/5OD4Pg+D7wfB8HwfB////8uD4Pg+D4nB8HwfB8Hw==');
    silentAudio.play().then(() => {
      console.log('Audio unlocked');
    }).catch(() => {});

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 · scripts/server.py (reported line 71)May include surrounding context.

python
GROQ_API_KEY = _load_groq_key()
GROQ_BASE = "https://api.groq.com/openai/v1"

GW_PORT, GW_TOKEN = _load_gateway_config()
OPENCLAW_BASE = f"http://127.0.0.1:{GW_PORT}"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The request defaults set language to zh and the default TTS voice to a Chinese voice, while transcription is also hard-coded with language: "zh". This imposes a specific language/locale behavior by default rather than offering a neutral default or explicit opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The server stores uploaded microphone and camera data on disk, then sends audio to Groq and image/text to OpenClaw and potentially onward to a cloud LLM, but this file contains no consent gate, disclosure mechanism, retention policy, or deletion logic. In a voice/video skill, that materially increases privacy risk because highly sensitive biometric and contextual data can leave the machine and persist locally without clear user awareness.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/server.py (reported line 128)May include surrounding context.

python
# Convert audio for Whisper
    wav_path = AUDIO_DIR / f"{req_id}.wav"
    try:
        result = subprocess.run(
            ["ffmpeg", "-y", "-i", str(audio_path), "-ar", "16000", "-ac", "1", str(wav_path)],
            capture_output=True, timeout=30,
        )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Speech transcription is hard-coded to Chinese even though the request includes a language parameter. In this context, forced misclassification can lead to incorrect transcripts being sent to the downstream agent, potentially causing privacy-impacting misunderstandings, unsafe actions, or leakage of sensitive spoken content through mistranscription.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/server.py (reported line 269)May include surrounding context.

python
for attempt in range(1, max_retries + 1):
        try:
            logger.info("TTS attempt %d/%d for %d chars", attempt, max_retries, len(text))
            result = subprocess.run(
                [
                    "edge-tts",
                    "--voice", voice,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
83% confidence
Finding

This ffmpeg concat flow writes a manifest file using unescaped paths inside single quotes. If a filename ever contains a quote or concat-metacharacters, ffmpeg may misparse the manifest and read unintended files; the current part filenames are derived from output_path, which is mostly internal, so exploitability is constrained but the pattern is still unsafe.

Content

Scanner excerpt · scripts/server.py (reported line 352)May include surrounding context.

python
"\n".join(f"file '{p}'" for p in part_paths),
                    encoding="utf-8",
                )
                result = subprocess.run(
                    [
                        "ffmpeg", "-y", "-f", "concat", "-safe", "0",
                        "-i", str(list_file), "-c", "copy", str(output_path),

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/server.py (reported line 381)May include surrounding context.

python
def _write_silent_mp3(path: Path):
    """Generate a short silent MP3 file using ffmpeg."""
    try:
        subprocess.run(
            [
                "ffmpeg", "-y", "-f", "lavfi", "-i",
                "anullsrc=r=24000:cl=mono", "-t", "0.5",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

In auto mode, the script will install missing system packages with Homebrew without an explicit confirmation step. That behavior changes the host environment and executes package-manager actions on the user's machine, which is risky for a setup script and especially sensitive in a skill that is intended to be easily triggered and deployed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script installs Python packages globally via pip3, including a fallback to --break-system-packages, without a strong warning or isolation. This can alter or damage the host Python environment, introduce dependency conflicts, and makes the script perform privileged-looking persistent environment changes beyond simple skill setup.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
97% confidence
Finding

This is true session persistence of a sensitive secret: the script stores the provided API key in a predictable file under the user's home directory for reuse across sessions. While intended for convenience, persistent plaintext secret storage increases the blast radius of local compromise and credential theft.

Content

Scanner excerpt · scripts/setup.sh (reported line 75)May include surrounding context.

sh
echo "   ⚠️  Groq API key not found."
    read -p "   Paste your Groq API key (or Enter to skip): " INPUT_KEY
    if [ -n "$INPUT_KEY" ]; then
      mkdir -p "$HOME/.openclaw/secrets"
      echo "$INPUT_KEY" > "$HOME/.openclaw/secrets/groq_api_key.txt"
      echo "   ✅ Saved"
    fi

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script installs and loads a launchd LaunchAgent, creating persistence at user login, without a prominent upfront warning or separate consent flow. Persistent background execution materially increases risk because this skill handles camera, microphone, and network communication, so users should explicitly approve always-on behavior.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
97% confidence
Finding

Although the token matched is generic, the actual line points to a LaunchAgents plist location used for persistence. In this script's context, that path is not inert metadata; it is directly used to deploy a user-level persistent service.

Content

Scanner excerpt · scripts/setup.sh (reported line 155)May include surrounding context.

sh
done
fi

PLIST="$HOME/Library/LaunchAgents/${PLIST_LABEL}.plist"
launchctl stop "$PLIST_LABEL" 2>/dev/null || true
launchctl unload "$PLIST" 2>/dev/null || true

Session Persistence

Medium
Category
Rogue Agent
Confidence
97% confidence
Finding

Although the token matched is generic, the actual line points to a LaunchAgents plist location used for persistence. In this script's context, that path is not inert metadata; it is directly used to deploy a user-level persistent service.

Content

Scanner excerpt · scripts/setup.sh (reported line 155)May include surrounding context.

sh
done
fi

PLIST="$HOME/Library/LaunchAgents/${PLIST_LABEL}.plist"
launchctl stop "$PLIST_LABEL" 2>/dev/null || true
launchctl unload "$PLIST" 2>/dev/null || true

Static analysis

No suspicious patterns detected.