T05 · Unauthorized Access and Privilege Escalation
- Location
api_server.py:38- Finding
Unauthenticated API Exposed on All Network Interfaces
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill appears to be a legitimate STT/TTS voice bridge, but it exposes a powerful unauthenticated audio service too broadly and recommends running it persistently as root.
Review carefully before installing. Use it only on localhost unless you add authentication and firewall controls, do not run it as root, avoid the recommended system-wide service as written, add upload/rate limits, and prefer pinned dependencies or a vetted lockfile. Treat any text sent through the default Edge TTS backend as leaving the local machine for Microsoft’s online TTS service.
api_server.py:38Unauthenticated API Exposed on All Network Interfaces
SKILL.md:103Root-Level Persistent systemd Service Exceeds Required Privileges
api_server.py:87Unbounded Uploads and Inference Permit Remote Resource Exhaustion
api_server.py:145Uploaded Audio Files Remain on Disk When Processing Fails
requirements.txt:1Unbounded and Unverified Third-Party Dependencies
The skill documentation is written in Chinese from the opening description onward, with no indication that other languages are supported or that the Chinese-only presentation is intentional for a region-specific use case. This creates a natural-language policy concern because the skill effectively imposes a specific language without user opt-in or justification.
The README sets EDGE_VOICE to zh-CN-XiaoxiaoNeural and the Piper default model to zh_CN-huayan-medium.onnx, which imposes a Chinese locale by default. The document does not offer an explicit user opt-in or explain that the skill is intentionally region/language-specific, so this appears to violate the language/locale policy criterion.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -X POST http://localhost:18790/audio/speech \
-H "Content-Type: application/json" \
-d '{
"input": "Hello, world!",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -X POST http://localhost:18790/audio/speech \
-H "Content-Type: application/json" \
-d '{
"input": "Hello, world!",
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Enable and start:
systemctl daemon-reload
systemctl enable voice-bridge-light.service
systemctl start voice-bridge-light.service
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Enable and start:
systemctl daemon-reload
systemctl enable voice-bridge-light.service
systemctl start voice-bridge-light.service
The Edge TTS path sends user-supplied text to Microsoft's online TTS service via edge_tts, which exposes potentially sensitive prompt content to a third party. In a voice bridge service, users may reasonably expect local processing, so the lack of explicit disclosure/consent and no option to enforce local-only synthesis creates a real privacy risk.
The call to engine.transcribe hard-codes language="zh", which constrains recognition to a specific language. This is a natural-language policy concern because the skill does not offer users a language choice or explain why a Chinese-only restriction is required.
The manifest description is written entirely in Chinese and provides no indication that users can opt into another language or locale. Under the policy, language or locale constraints should either offer a choice or be clearly documented as justified for a region-specific tool.
The transcription handler reads the uploaded file and persists it to a temporary .wav file before processing. Although the file is later deleted, this is still a file-write operation affecting user data, and the code provides no user-facing notice, prompt, or descriptive comment explaining that uploaded audio is written to disk.
The dependency uses a lower-bound constraint (flask>=2.3.0) instead of a pinned or tightly bounded version, which makes builds non-reproducible and can cause installation of unexpected vulnerable or breaking releases over time. In a skill environment, this increases supply-chain risk because the actual installed version cannot be reliably audited.
flask>=2.3.0
flask-cors>=4.0.0
numpy>=1.24.0
soundfile>=0.12.0
Flask has known advisories, and because the manifest does not pin an exact version, it is impossible to verify whether deployed environments are affected or not. This uncertainty materially weakens vulnerability management even though the file alone does not prove an exploitable Flask flaw is present.
The dependency uses an unpinned minimum version (flask-cors>=4.0.0), so deployments may resolve to different versions with different security properties. This weakens reproducibility and makes it harder to ensure that vulnerable releases are not introduced.
flask>=2.3.0
flask-cors>=4.0.0
numpy>=1.24.0
soundfile>=0.12.0
piper-tts>=1.2.0
Flask-CORS has multiple published advisories, but the unpinned requirement prevents verification of whether a safe release is installed. Given that CORS behavior affects browser trust boundaries, unresolved version ambiguity is a meaningful security weakness.
Using numpy>=1.24.0 allows any newer version to be installed, which can introduce unreviewed security issues or incompatible behavior. Even for a common library, unpinned resolution increases supply-chain uncertainty and audit difficulty.
flask>=2.3.0
flask-cors>=4.0.0
numpy>=1.24.0
soundfile>=0.12.0
piper-tts>=1.2.0
faster-whisper>=0.10.0
NumPy has known advisories, and the floating version constraint makes it impossible to confirm whether the runtime version is affected. While many NumPy issues are context-dependent, unverifiable dependency state still creates audit and supply-chain risk.
The soundfile package is not pinned to an exact version, so future installs may silently pull in a release with security or stability regressions. This is a dependency hygiene weakness that can become exploitable if a compromised or vulnerable version is resolved.
flask>=2.3.0
flask-cors>=4.0.0
numpy>=1.24.0
soundfile>=0.12.0
piper-tts>=1.2.0
faster-whisper>=0.10.0
edge-tts>=6.1.6
The piper-tts dependency is specified as a minimum version only, which permits uncontrolled upgrades during installation. That creates a supply-chain exposure and prevents reliable determination of what code will run in production.
flask-cors>=4.0.0
numpy>=1.24.0
soundfile>=0.12.0
piper-tts>=1.2.0
faster-whisper>=0.10.0
edge-tts>=6.1.6
pydub>=0.25.0
The faster-whisper dependency is unpinned, so installation results may vary across environments and over time. This can introduce vulnerable or malicious upstream changes without any manifest modification in the skill itself.
numpy>=1.24.0
soundfile>=0.12.0
piper-tts>=1.2.0
faster-whisper>=0.10.0
edge-tts>=6.1.6
pydub>=0.25.0
pyyaml>=6.0.1
The edge-tts package is allowed to float above a minimum version, which makes dependency resolution unpredictable and weakens supply-chain assurance. The risk is elevated by the inability to confirm which exact code will be installed.
soundfile>=0.12.0
piper-tts>=1.2.0
faster-whisper>=0.10.0
edge-tts>=6.1.6
pydub>=0.25.0
pyyaml>=6.0.1
The pydub dependency is not pinned, allowing future installations to resolve to arbitrary newer releases. This creates a low-severity but real supply-chain and reproducibility risk.
piper-tts>=1.2.0
faster-whisper>=0.10.0
edge-tts>=6.1.6
pydub>=0.25.0
pyyaml>=6.0.1
The pyyaml dependency is unpinned, which is especially concerning because YAML parsers have a history of security-sensitive issues. Without an exact version, the installed release cannot be confidently assessed for known vulnerabilities or safe parsing behavior.
faster-whisper>=0.10.0
edge-tts>=6.1.6
pydub>=0.25.0
pyyaml>=6.0.1
PyYAML has a history of deserialization and input-validation vulnerabilities, and the manifest does not pin a version, so affected deployments cannot be ruled out. In a skill that may process configuration or user-provided YAML, this uncertainty is more dangerous because unsafe parser behavior can lead to serious compromise.
No suspicious patterns detected.