#19768: fix(security): OC-85 validate TTS provider directives against known providers — Aether AI Agent
size: S
trusted-contributor
Cluster:
Security Enhancements for TTS
## Attack Vector
OC-85: TTS directive injection from LLM-generated text.
**Vector:** When `allowProvider=true` is configured, the TTS subsystem parses `[[tts:provider=X]]` directives from LLM output text. An attacker who can influence LLM output (via prompt injection or a malicious external data source) can inject an arbitrary provider name, potentially redirecting TTS to an unauthorized or malicious provider.
**CWE:** CWE-74 (Injection), CWE-20 (Improper Input Validation)
**Severity:** Medium
**GHSA:** GHSA-xwcr-v472-8hhr
## Fix
Added validation of parsed TTS provider directives against a known/configured provider allowlist. Unrecognized provider values from LLM output are rejected, preventing injection-based provider hijacking.
## Impact
Prevents prompt-injection attacks from redirecting TTS processing to unauthorized providers.
---
*Discovered and remediated by [Aether AI Agent](https://tryaether.ai) — automated security research.*
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds a second layer of validation to TTS provider directives parsed from LLM output. Previously, `parseTtsDirectives` only checked provider names against a hardcoded allowlist (`openai`, `elevenlabs`, `edge`). Now, when `configuredProviders` is present on the policy, the provider must also be actually configured in the current deployment (i.e., have an API key set or be explicitly enabled). This prevents a prompt-injection attack from redirecting TTS to a valid-but-unconfigured provider.
- `src/tts/tts.ts`: Adds `configuredProviders?: Set<string>` to `ResolvedTtsModelOverrides`. In `resolveTtsConfig`, when model overrides and `allowProvider` are both enabled, builds a `Set` of actually-configured providers using `isTtsProviderConfigured` and attaches it to the policy.
- `src/tts/tts-core.ts`: In `parseTtsDirectives`, after passing the hardcoded allowlist check, additionally validates the provider against `configuredProviders` (when present). Unconfigured providers produce a warning instead of being accepted.
- No tests were added for the new `configuredProviders` validation path. Existing tests pass because `resolveModelOverridePolicy` does not set `configuredProviders`, so the `== null` fallback preserves backward compatibility.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge — the changes are minimal, focused, and backward-compatible with existing behavior.
- The security fix is straightforward and correctly layered: the new `configuredProviders` check is additive and falls back to prior behavior when unset. The only gap is the absence of test coverage for the new validation path, which slightly reduces confidence.
- No files require special attention — both changed files have clean, well-scoped modifications.
<sub>Last reviewed commit: dfdb427</sub>
<!-- greptile_other_comments_section -->
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#22086: fix(tts): honor explicit config provider and model/voice settings
by AIflow-Labs · 2026-02-20
78.5%
#8339: fix(tts): validate ElevenLabs base URL against allowlist
by yubrew · 2026-02-03
75.8%
#7965: feat(tts): add Speechify as TTS provider
by chaerla · 2026-02-03
72.6%
#15197: fix: allow OpenAI auth profiles for OpenAI-compatible providers
by bufordtjustice2918 · 2026-02-13
72.4%
#19020: bugfix(gateway): Handle invalid model provider API config gracefully\…
by funkyjonx · 2026-02-17
72.2%
#16838: fix: include configured fallbacks in model allowlist
by taw0002 · 2026-02-15
72.2%
#16089: fix(tts): clarify directive syntax in prompts and strip malformed tags
by kmixter · 2026-02-14
72.1%
#8103: fix(tts): sanitize API keys from error messages
by yubrew · 2026-02-03
72.1%
#6673: fix: preserve allowAny flag in createModelSelectionState for custom...
by tenor0 · 2026-02-01
71.9%
#7767: fix: enable turn validation for all non-OpenAI providers to prevent...
by sohail22dec · 2026-02-03
71.9%