Back to skill

Security audit

Gemini Voice Assistant

Security checks for vulnerabilities and agentic risk

Overview

This Gemini voice assistant is mostly purpose-aligned, but it can send broad WhatsApp-triggered text/audio and arbitrary local audio paths to Google with weak scoping and unsafe temporary output handling.

Review before installing. Use this only if you are comfortable sending selected WhatsApp text/audio to Google's Gemini service. Narrow the triggers to explicit commands, restrict audio_path to trusted upload files, avoid sensitive recordings, and fix the predictable /tmp output path before using it in a shared or multi-user environment.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/handler.py:76
Finding

Unrestricted Local Audio File Read and External Disclosure

Content
View full analysis
dict: """Main entry point for Gemini Assistant.""" chat_id = request_data.get("chat_id", "unknown") text_input = request_data.get("text") audio_path = request_data.get("audio_path") system_instruction = request_data.get("system_instruction") safe_id = str(chat_id).replace("@", "_").replace("+", "").replace(".", "_") voice_output_path = f"/tmp/gemini_voice_{safe_id}.ogg" try: # Process with Gemini result = asyncio.run(_process_with_gemini( audio_path=audio_path, text_input=text_input, system_instruction=system_instruction )) ``` ### Technical Analysis The handler accepts `audio_path` directly from `request_data` and passes it to `librosa.load()` without verifying that the path belongs to an authorized upload directory. The implementation does not canonicalize the path, reject symbolic links, check file ownership, enforce an allowlisted file type, or verify that the caller is authorized to access the selected file. If the process can decode the selected file as audio, its contents are converted to PCM and transmitted to the external Gemini Live API. Consequently, this is not only a local file-read issue but also an external data-disclosure path. Exploitat ...[truncated 1247 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/handler.py:137
Finding

Predictable Shared Temporary Output Enables Symlink Overwrite and Cross-Request Collisions

Content
View full analysis
dict: """Main entry point for Gemini Assistant.""" chat_id = request_data.get("chat_id", "unknown") text_input = request_data.get("text") audio_path = request_data.get("audio_path") system_instruction = request_data.get("system_instruction") safe_id = str(chat_id).replace("@", "_").replace("+", "").replace(".", "_") voice_output_path = f"/tmp/gemini_voice_{safe_id}.ogg" try: # Process with Gemini result = asyncio.run(_process_with_gemini( audio_path=audio_path, text_input=text_input, system_instruction=system_instruction )) raw_pcm = result.get("raw_pcm", b"") response = {} # Convert voice to OGG if we have audio if raw_pcm: _pcm_to_ogg_opus(raw_pcm, voice_output_path) ``` ### Technical Analysis The generated OGG filename is placed directly in the globally shared `/tmp` directory and is predictable from `chat_id`. The sanitization only replaces `@`, `+`, and `.`, leaving path separators and other unsafe characters unchanged. The code does not create the destination exclusiv ...[truncated 1975 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (15)

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/handler.py (reported line 21)May include surrounding context.

python
from google import genai
from google.genai import types

# Load .env file manually if present
env_path = Path(__file__).parent / ".env"
if env_path.exists():
    with open(env_path) as f:

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/handler.py (reported line 22)May include surrounding context.

python
from google.genai import types

# Load .env file manually if present
env_path = Path(__file__).parent / ".env"
if env_path.exists():
    with open(env_path) as f:
        for line in f:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/handler.py (reported line 111)May include surrounding context.

python
sf.write(wav_path, audio_np, SAMPLE_RATE_OUT, format="WAV", subtype="PCM_16")

    try:
        env = os.environ.copy()
        env["LD_LIBRARY_PATH"] = "/usr/lib/x86_64-linux-gnu"
        result = subprocess.run(
            [

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · scripts/handler.py (reported line 182)May include surrounding context.

python
ice_output_path}"
        
        return response
        
    except Exception as e:
        error_msg = str(e)
        print(f"[gemini-assistant] Error: {error_msg}")
        import traceback
        traceback.print_exc()
        
        return {
            "message": f"Sorry, an error occurred: {str(e)}"
        }


def main():
    """CLI entry point."""
    parser = argparse.ArgumentParser(description="Gemini Assistant")
    parser.add_argument("input_text", nargs="?", help="Text input to send to Gemini")
    parser.add_argument("--audio", "-a", help="Path to audio file for voice input")
    parser.add_argument("--system", "-s", help="Custom system instruction")
    
    args = parser.parse_args()
    
    request_data = {
        "chat_id": "cli",
        "text": args.input_text,
        "audio_path": args.audio,
        "system_instruction": args.system
    }
    
    result = handle_request(request_data)
    print(json.dumps(result, indent=2, ensure_ascii=False))


if __name_

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The trigger list includes very common words and phrases such as "ai," "help," "what is," "how to," and "tell me," which can cause accidental activation during ordinary conversation. In a WhatsApp voice/audio context, this can unintentionally route user content to the skill and onward to the external Gemini API, creating privacy and consent risks even without malicious code.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documentation advertises execution patterns that rely on environment variables and shell commands, but it does not declare any explicit tool scope or permissions. This weakens security boundaries and informed review because users and orchestrators cannot easily tell that the skill may access secrets from the environment and invoke shell-dependent behavior such as FFmpeg.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill processes user voice and text through Google's Gemini API, but the description does not clearly warn users that their prompts and audio are transmitted to a third-party service. This creates a privacy and compliance risk because users may unknowingly submit sensitive spoken content, credentials, or personal data to an external provider.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring states this is a "General purpose AI assistant" that "Supports text and voice interactions," and the handler accepts plain text input via request_data and CLI arguments. That is materially broader than the manifest's stated scope of speaking to the AI and getting spoken responses in a voice-to-voice interaction flow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code sends user-provided text or audio to Google's Gemini API without any consent gate, warning, or explicit disclosure in this execution path. In a voice-assistant context, this is meaningful because highly sensitive spoken content may be transmitted off-box to a third party unexpectedly.

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/handler.py (reported line 113)May include surrounding context.

python
try:
        env = os.environ.copy()
        env["LD_LIBRARY_PATH"] = "/usr/lib/x86_64-linux-gnu"
        result = subprocess.run(
            [
                FFMPEG, "-i", wav_path,
                "-c:a", "libopus",

Ssd 1

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Allowing a caller to supply arbitrary natural-language system instructions lets the caller semantically override the assistant's intended behavior and safety posture. In an agent skill, this can weaken trust boundaries, bypass product intent, or cause unexpected external disclosures and unsafe outputs even without code execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest hard-codes the language to "en", which imposes a specific language choice without indicating that users can select another locale or that the constraint is required. This is a natural-language policy concern because it limits language behavior by default without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest declares an external API credential requirement but provides no user-facing disclosure that voice or text inputs may be transmitted to Google's Gemini service. For a voice assistant, this increases the likelihood that sensitive spoken content is sent off-platform without informed user awareness or consent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring for _process_with_gemini says it "Returns both audio and text response," but the implementation only accumulates response.data chunks and returns a dict containing raw_pcm. No text response is extracted, stored, or returned anywhere in the function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

Custom system instructions are forwarded to the external Gemini service without any explicit disclosure or filtering. While system instructions are less sensitive than raw voice content in many cases, they may still contain proprietary prompts, internal policy, or hidden operational context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.