fix: harden voice prompt cache loading and SPA path guard (#429)

Two small safety improvements:

1. Voice prompt cache (cache.py): add weights_only=True to torch.load()
   so cached .prompt files are loaded using the safe unpickler instead of
   the unrestricted pickle deserializer. This follows the PyTorch 2.6+
   best practice of opting in to safe loading for all torch.load() calls.

2. SPA catch-all (app.py): replace str.startswith() path guard with
   Path.is_relative_to(). The string prefix check passes for sibling
   paths like /app/frontend_evil/ that share the /app/frontend prefix.
   is_relative_to() correctly tests directory containment.
This commit is contained in:
Junghwan
2026-04-16 01:49:19 -07:00
committed by GitHub
parent a1807be04d
commit 1da16cfc57
2 changed files with 2 additions and 2 deletions
+1 -1
View File
@@ -135,7 +135,7 @@ def _mount_frontend(application: FastAPI) -> None:
async def serve_spa(full_path: str):
file_path = (frontend_dir / full_path).resolve()
# Guard against path traversal — only serve files inside frontend_dir
if full_path and file_path.is_file() and str(file_path).startswith(str(frontend_dir)):
if full_path and file_path.is_file() and file_path.is_relative_to(frontend_dir):
return FileResponse(file_path)
return FileResponse(frontend_dir / "index.html", media_type="text/html")
+1 -1
View File
@@ -64,7 +64,7 @@ def get_cached_voice_prompt(
cache_file = _get_cache_dir() / f"{cache_key}.prompt"
if cache_file.exists():
try:
prompt = torch.load(cache_file)
prompt = torch.load(cache_file, weights_only=True)
_memory_cache[cache_key] = prompt
return prompt
except Exception: