T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/elevenlabs_speech.py:5
- Finding
- Unnecessarily Broad Loading of an Ancestor .env File## 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
- ## 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") ```
