Back to skill

Security audit

Miranda ElevenLabs Speech (TTS/STT)

Security checks for vulnerabilities and agentic risk

Overview

The skill performs the advertised ElevenLabs speech tasks, but it reads an overbroad parent .env file and sends user text or audio to ElevenLabs without enough privacy warning.

Review before installing. Use only non-sensitive text or audio unless you are comfortable sending it to ElevenLabs, store ELEVENLABS_API_KEY securely, and be aware that the TTS script may read a parent .env file outside the skill directory. There is no evidence of destructive behavior, persistence, hidden command execution, or unrelated data exfiltration.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/elevenlabs_speech.py:5
Finding

Unnecessarily Broad Loading of an Ancestor .env File

Content
View full analysis

Vulnerability Details

File Location: scripts/elevenlabs_speech.py, lines 5-8
Vulnerability Type: Insecure environment configuration and excessive secret exposure
Risk Level: Medium

Vulnerable Code

python
from dotenv import load_dotenv

# Load environment variables from workspace .env
load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), '..', '..', '..', '.env'))

Technical Analysis

The module automatically loads an .env file by traversing three parent directories from scripts/elevenlabs_speech.py. From the audited project layout, this resolves outside the Skill's project directory rather than to the documented workspace-root .env.

load_dotenv() parses all variables in that external file and adds them to the process environment, even though this Skill only needs ELEVENLABS_API_KEY. Loading an unrelated ancestor configuration file therefore exceeds the minimum privilege and data-access scope required for the declared text-to-speech functionality.

The behavior occurs as an import-time side effect, so merely importing ElevenLabsClient triggers the external configuration read. The code does not transmit arbitrary loaded variables, and the reviewed network requests send only the ElevenLabs API key and functionality-specific text or request data. Nevertheless, the broad load exposes unrelated configuration values to the process and can cause the client to use an unintended API credential.

Attack Path

  1. An attacker or another local project gains the ability to create or modify the .env file at the hardcoded ancestor path.
  2. A user executes the script or imports scripts.elevenlabs_speech.
  3. The import-time load_dotenv() call reads every variable from the attacker-controlled or unrelated file into the process environment.
  4. If ELEVENLABS_API_KEY was not already defined, the injected value becomes available to ElevenLabsClient.
  5. The client authenticates ElevenLabs requests using that uninten ...[truncated 1066 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove import-time loading of an .env file outside the project.
  2. Prefer a credential supplied explicitly to ElevenLabsClient or inherited from the already configured process environment.
  3. If .env support is required, resolve it against an explicit and validated project/workspace root rather than traversing ancestor directories.
  4. Parse and retain only ELEVENLABS_API_KEY instead of importing all entries into the process environment.
  5. Do not override an existing environment value, and fail closed with a clear error when the key is absent.
  6. Restrict the .env file's permissions to its owner and document its exact expected location.
  7. Move configuration loading into the CLI entry point so importing the client library does not read external files as a side effect.

A safer pattern is:

python
from pathlib import Path
from dotenv import dotenv_values
import os

PROJECT_ROOT = Path(__file__).resolve().parents[1]
config = dotenv_values(PROJECT_ROOT / ".env")

api_key = os.getenv("ELEVENLABS_API_KEY") or config.get("ELEVENLABS_API_KEY")
if not api_key:
    raise ValueError("ELEVENLABS_API_KEY is required")
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code is narrowly focused on speech-to-text. It reads an audio file from disk and sends it to ElevenLabs' /speech-to-text endpoint with transcription-related options such as language, speaker count, and timestamp granularity. There is no text-to-speech functionality, no endpoint for voice synthesis, and no handling of text input for conversion into audio. The speech-to-text portion of the description is accurate, but the overall declared purpose overstates the implemented capabilities by claiming both TTS and STT.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code accurately supports part of the description: high-quality text-to-speech using ElevenLabs and listing available voices. However, it does not contain any code for uploading audio, transcribing speech, handling voice messages, or performing speech-to-text. The primary mismatch is that the declared description presents the skill as both TTS and STT, while the implementation is TTS-only plus voice enumeration. Loading an API key from a .env file and making outbound requests to ElevenLabs are consistent supporting details, not separate mismatches.

Content

No source excerpt is available for this finding.

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

python
from pathlib import Path
from dotenv import load_dotenv

# Load environment variables from workspace .env
load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), '..', '..', '..', '.env'))

class ElevenLabsClient:

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

python
from dotenv import load_dotenv

# Load environment variables from workspace .env
load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), '..', '..', '..', '.env'))

class ElevenLabsClient:
    """Client for ElevenLabs Text-to-Speech API"""

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents use of environment variables for an API key and remote ElevenLabs API calls, but it declares no tool scope or permissions. This creates an undeclared capability boundary where the agent may access secrets and make network requests without transparent authorization, increasing the risk of unintended data egress or misuse in environments that rely on manifest-declared restrictions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill encourages sending user text and audio to ElevenLabs for TTS/STT but does not clearly warn that potentially sensitive content leaves the local environment and is processed by a third-party service. In an agent context, this can lead to inadvertent disclosure of private conversations, voice biometrics, or regulated data because users and integrators are not prompted to assess data-handling risks.

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

python
def __init__(self, api_key=None):
        self.api_key = api_key or os.getenv('ELEVENLABS_API_KEY')
        self.base_url = "https://api.elevenlabs.io/v1"
    
    def transcribe(self, audio_file_path, language_code=None, tag_audio_events=True, 
                   num_speakers=None, timestamps_granularity="word"):

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

python
def __init__(self, api_key=None):
        self.api_key = api_key or os.getenv('ELEVENLABS_API_KEY')
        self.base_url = "https://api.elevenlabs.io/v1"
    
    def transcribe(self, audio_file_path, language_code=None, tag_audio_events=True, 
                   num_speakers=None, timestamps_granularity="word"):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code uploads the entire user-supplied audio file to ElevenLabs' external speech-to-text API, which can expose sensitive voice content, background speech, or embedded personal data to a third party. In this skill context, external transmission is expected for cloud transcription, but the lack of explicit user-facing notice or consent still creates a real privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest describes both Text-to-Speech and Speech-to-Text capabilities, including transcribing voice messages, but this file only provides a text_to_speech method and a get_voices helper. There is no speech-to-text, transcription, or audio-input handling logic anywhere in the implementation or CLI.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The code transmits user-supplied text to an external network service, which creates a genuine data exposure boundary. In the context of a speech generation skill this behavior is core functionality, so it is not malicious, but it is still a real privacy/security concern if sensitive text can be sent without clear notice or policy controls.

Content

Scanner excerpt · scripts/elevenlabs_speech.py (reported line 43)May include surrounding context.

python
}
        
        try:
            response = requests.post(url, headers=headers, json=payload, timeout=60)
            response.raise_for_status()
            
            # Save audio file

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-provided text is sent to a third-party API, which can expose sensitive or private content if users are not clearly informed that their input leaves the local environment. In a speech skill, external transmission is expected, but the absence of explicit disclosure and consent still creates a real privacy risk, especially if users paste secrets, personal data, or proprietary text.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The setup instructions require a live API credential but do not warn that the key is sensitive or advise secure storage practices. This increases the chance of accidental exposure through checked-in .env files, logs, shell history, or copied examples, which can enable unauthorized use of the ElevenLabs account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The code accesses an API credential from the environment, which falls under sensitive credential handling. The file does not include any warning, comment, or user-facing notice explaining that an external service credential is required and will be used for authenticated requests.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The class docstring says this is a client for the ElevenLabs Text-to-Speech API, but the class also includes get_voices(), which accesses a separate voice-listing capability. This is a documentation-to-code mismatch in stated intent, even though the extra capability is related to the same service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The client reads ELEVENLABS_API_KEY from the environment and uses it in outbound HTTP headers. Although this is functionally necessary, the file lacks a clear warning or note to users that the skill depends on a sensitive credential and will use it for external API calls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The code writes API response content to output_path, modifying the local filesystem. Although the CLI exposes an --output argument, there is no explicit notice in the docstring, help text, or runtime messaging that the operation creates or overwrites a local file.

Content

No source excerpt is available for this finding.