T09 · Insecure Skill Coding Practices
Warning
- Location
- config.example.json:2
- Finding
- Plaintext HTTP Configuration Permits Exposure of Sensitive Video Data and API Credentials<![CDATA[ ## Vulnerability Details **File Location**: `config.example.json:2-21`; related network operations in `src/video_skill_extractor/transcribe.py:16-31` and `src/video_skill_extractor/ai_adapter.py:48-55, 122-130` **Vulnerability Type**: Sensitive data transmitted over an unencrypted network connection **Risk Level**: Medium ### Vulnerable Code ```json { "transcription": { "provider": "whisper-local", "base_url": "http://YOUR_SERVER_IP:8003", "model": "faster-whisper-large-v3", "api_key_env": null, "timeout_s": 60 }, "reasoning": { "provider": "openai-compatible", "base_url": "http://YOUR_SERVER_IP:8001", "model": "qwen35-a3b", "api_key_env": null, "timeout_s": 60 }, "vlm": { "provider": "openai-compatible", "base_url": "http://YOUR_SERVER_IP:8002", "model": "gemma3-vlm", "api_key_env": null, "timeout_s": 60 } } ``` The transcription client uploads the source media and an optional bearer credential to the configured endpoint: ```python endpoint = str(provider.base_url).rstrip("/") + "/v1/audio/transcriptions" headers: dict[str, str] = {} api_key = provider.api_key() if api_key: headers["Authorization"] = f"Bearer {api_key}" with httpx.Client(timeout=provider.timeout_s) as client: with video_path.open("rb") as f: files = {"file": (video_path.name, f, "video/mp4")} data = { "model": provider.model, "response_format": response_format, "timestamp_granularities": timestamp_granularities, } res = client.post(endpoint, files=files, data=data, headers=headers) res.raise_for_status() payload = res.json() ``` The AI adapter similarly uses the configured URL and credential: ```python model = OpenAIChatModel( provider.model, provider=OpenAIProvider( base_url=str(provider.base_url).rstrip("/"), api_key=provider.api_key() or "dummy-local-key", ), ) ``` ### Technical Anal ...[truncated 2150 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require HTTPS for every non-loopback provider endpoint. 2. Add configuration validation that rejects plaintext HTTP unless the hostname is an explicit loopback address such as `127.0.0.1`, `localhost`, or `::1`. 3. If isolated LAN deployments must remain supported, require an explicit security override such as `allow_insecure_http: true` and display a prominent warning. 4. Never send an API key over HTTP. Reject configurations combining `api_key_env` with an insecure endpoint. 5. Change `config.example.json` to use `https://` placeholders or loopback-only HTTP addresses. 6. Configure certificate verification normally and provide a documented custom-CA option for internal deployments rather than disabling TLS verification. 7. Document that video files, transcripts, and frame images are transmitted to the selected providers. 8. Consider adding provider-level data-sharing confirmation before transmitting media to a non-local host. ]]>
