Skip to content

Commit 3730c8d

Browse files
committed
Hide TTS filename behind random token
1 parent d854940 commit 3730c8d

File tree

2 files changed

+157
-120
lines changed

2 files changed

+157
-120
lines changed

homeassistant/components/tts/__init__.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import mimetypes
1414
import os
1515
import re
16+
import secrets
1617
import subprocess
1718
import tempfile
1819
from typing import Any, Final, TypedDict, final
@@ -540,6 +541,9 @@ def __init__(
540541
self.file_cache: dict[str, str] = {}
541542
self.mem_cache: dict[str, TTSCache] = {}
542543

544+
# filename <-> token
545+
self.filename_token: dict[str, str] = {}
546+
543547
def _init_cache(self) -> dict[str, str]:
544548
"""Init cache folder and fetch files."""
545549
try:
@@ -656,7 +660,17 @@ async def async_get_url_path(
656660
engine_instance, cache_key, message, use_cache, language, options
657661
)
658662

659-
return f"/api/tts_proxy/{filename}"
663+
# Use a randomly generated token instead of exposing the filename
664+
token = self.filename_token.get(filename)
665+
if not token:
666+
# Keep extension (.mp3, etc.)
667+
token = secrets.token_urlsafe(16) + os.path.splitext(filename)[1]
668+
669+
# Map token <-> filename
670+
self.filename_token[filename] = token
671+
self.filename_token[token] = filename
672+
673+
return f"/api/tts_proxy/{token}"
660674

661675
async def async_get_tts_audio(
662676
self,
@@ -910,11 +924,15 @@ def async_remove_from_mem(_: datetime) -> None:
910924
),
911925
)
912926

913-
async def async_read_tts(self, filename: str) -> tuple[str | None, bytes]:
927+
async def async_read_tts(self, token: str) -> tuple[str | None, bytes]:
914928
"""Read a voice file and return binary.
915929
916930
This method is a coroutine.
917931
"""
932+
filename = self.filename_token.get(token)
933+
if not filename:
934+
raise HomeAssistantError(f"{token} was not recognized!")
935+
918936
if not (record := _RE_VOICE_FILE.match(filename.lower())) and not (
919937
record := _RE_LEGACY_VOICE_FILE.match(filename.lower())
920938
):
@@ -1076,6 +1094,7 @@ def __init__(self, tts: SpeechManager) -> None:
10761094
async def get(self, request: web.Request, filename: str) -> web.Response:
10771095
"""Start a get request."""
10781096
try:
1097+
# filename is actually token, but we keep its name for compatibility
10791098
content, data = await self.tts.async_read_tts(filename)
10801099
except HomeAssistantError as err:
10811100
_LOGGER.error("Error on load tts: %s", err)

0 commit comments

Comments
 (0)