Back to skill

Security audit

Local Voice (FluidAudio TTS/STT)

Security checks across malware telemetry and agentic risk

Overview

This appears to be a legitimate local voice service, but it needs review because it installs an always-on background daemon, may download models despite offline claims, and logs transcript snippets locally.

Install only if you are comfortable with a user-level macOS background service that starts at login, listens on localhost, installs/builds dependencies, and may download speech models before offline use. Avoid using it for sensitive speech unless transcript-content logging is removed or disabled, and make sure you know how to unload the LaunchAgent and delete the installed files.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (20)

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill clearly instructs users to run shell commands, build software, copy binaries/frameworks, and modify launchd configuration, yet it declares no permissions. This creates a transparency and trust problem because users and tooling cannot accurately assess the skill's operational scope before execution.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented behavior extends beyond the stated purpose by installing additional dependencies, creating a persistent background daemon, exposing localhost HTTP endpoints, and referencing optional ffmpeg conversion not disclosed in the description. This mismatch is dangerous because users may approve a 'local voice' skill without realizing it changes persistence state and exposes a local API surface.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The script creates and loads a user LaunchAgent that runs StellaVoice automatically at login and keeps it alive. For a local voice daemon this may be functionally related, but it is still persistence behavior that expands the installation footprint beyond a one-shot setup and should be clearly disclosed because it leaves a continuously running local service exposed on the host.

Description-Behavior Mismatch

Low
Confidence
84% confidence
Finding
The setup script installs espeak-ng via Homebrew without the manifest disclosing that an additional package manager action and dependency installation will occur. This is not inherently malicious, but undisclosed package installation changes the system state and can surprise users or violate least astonishment in security-sensitive environments.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The code initializes STT by calling AsrModels.downloadAndLoad(version: .v3), which causes a network download at runtime despite the skill description claiming voice processing runs entirely on-device. This is a real security and privacy issue because users or integrators may rely on the local-only claim for air-gapped, privacy-sensitive, or compliance-constrained deployments, and the unexpected outbound fetch can leak metadata and break trust assumptions.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The setup creates lasting changes in the user's environment, including installed packages, copied executables/frameworks, log paths, and a LaunchAgent that runs automatically, but it does not warn the user about persistence or cleanup. While not inherently malicious, undisclosed persistence increases the chance of accidental exposure, troubleshooting difficulty, and stale background services remaining active.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The /transcribe endpoint logs part of the transcript content with print, which can expose sensitive spoken data in logs, terminals, process supervisors, or centralized log collectors. Because transcription commonly handles personal, confidential, or authentication-related speech, even partial transcript logging creates unnecessary privacy exposure without user consent or minimization.

Session Persistence

Medium
Category
Rogue Agent
Content
cat > ~/Library/LaunchAgents/com.stella.tts.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.stella.tts</string>
Confidence
91% confidence
Finding
plist

Session Persistence

Medium
Category
Rogue Agent
Content
<key>StandardErrorPath</key>
    <string>$HOME/.clawdbot/logs/stella-tts.err.log</string>
</dict>
</plist>
EOF

launchctl load ~/Library/LaunchAgents/com.stella.tts.plist
Confidence
91% confidence
Finding
plist

Session Persistence

Medium
Category
Rogue Agent
Content
# Create LaunchAgent
echo "⚙️  Creating LaunchAgent..."
cat > "$PLIST_DIR/com.stella.voice.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Confidence
94% confidence
Finding
PLIST

Session Persistence

Medium
Category
Rogue Agent
Content
# Create LaunchAgent
echo "⚙️  Creating LaunchAgent..."
cat > "$PLIST_DIR/com.stella.voice.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Confidence
94% confidence
Finding
plist

Session Persistence

Medium
Category
Rogue Agent
Content
echo "⚙️  Creating LaunchAgent..."
cat > "$PLIST_DIR/com.stella.voice.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
Confidence
92% confidence
Finding
plist

Session Persistence

Medium
Category
Rogue Agent
Content
echo "⚙️  Creating LaunchAgent..."
cat > "$PLIST_DIR/com.stella.voice.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
Confidence
92% confidence
Finding
PLIST

Session Persistence

Medium
Category
Rogue Agent
Content
cat > "$PLIST_DIR/com.stella.voice.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.stella.voice</string>
Confidence
91% confidence
Finding
plist

Session Persistence

Medium
Category
Rogue Agent
Content
<key>WorkingDirectory</key>
    <string>${HOME}</string>
</dict>
</plist>
EOF

# Load service
Confidence
88% confidence
Finding
plist

Session Persistence

Medium
Category
Rogue Agent
Content
# Load service
echo "🔄 Loading service..."
launchctl unload "$PLIST_DIR/com.stella.voice.plist" 2>/dev/null || true
launchctl load "$PLIST_DIR/com.stella.voice.plist"

# Wait for startup
Confidence
95% confidence
Finding
PLIST

Session Persistence

Medium
Category
Rogue Agent
Content
# Load service
echo "🔄 Loading service..."
launchctl unload "$PLIST_DIR/com.stella.voice.plist" 2>/dev/null || true
launchctl load "$PLIST_DIR/com.stella.voice.plist"

# Wait for startup
Confidence
95% confidence
Finding
plist

Session Persistence

Medium
Category
Rogue Agent
Content
# Load service
echo "🔄 Loading service..."
launchctl unload "$PLIST_DIR/com.stella.voice.plist" 2>/dev/null || true
launchctl load "$PLIST_DIR/com.stella.voice.plist"

# Wait for startup
echo "⏳ Waiting for models to load (~15s)..."
Confidence
97% confidence
Finding
launchctl load

Session Persistence

Medium
Category
Rogue Agent
Content
# Load service
echo "🔄 Loading service..."
launchctl unload "$PLIST_DIR/com.stella.voice.plist" 2>/dev/null || true
launchctl load "$PLIST_DIR/com.stella.voice.plist"

# Wait for startup
echo "⏳ Waiting for models to load (~15s)..."
Confidence
97% confidence
Finding
PLIST

Session Persistence

Medium
Category
Rogue Agent
Content
# Load service
echo "🔄 Loading service..."
launchctl unload "$PLIST_DIR/com.stella.voice.plist" 2>/dev/null || true
launchctl load "$PLIST_DIR/com.stella.voice.plist"

# Wait for startup
echo "⏳ Waiting for models to load (~15s)..."
Confidence
97% confidence
Finding
plist

VirusTotal

66/66 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.