Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion moshi/moshi/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,25 @@ async def handle_chat(self, request):
voice_prompt_filename = request.query["voice_prompt"]
requested_voice_prompt_path = None
if voice_prompt_filename is not None:
requested_voice_prompt_path = os.path.join(self.voice_prompt_dir, voice_prompt_filename)
# Reject path traversal / absolute paths: restrict to a bare basename
# within voice_prompt_dir. Without this, an attacker could supply
# values like "../../etc/passwd" or "/abs/path/malicious.pt" and
# have the server torch.load() an arbitrary file (RCE via pickle).
safe_name = os.path.basename(voice_prompt_filename)
if (
not safe_name
or safe_name != voice_prompt_filename
or safe_name in (".", "..")
or os.path.isabs(voice_prompt_filename)
or os.sep in voice_prompt_filename
or (os.altsep and os.altsep in voice_prompt_filename)
):
raise web.HTTPBadRequest(reason="Invalid voice_prompt name")
voice_prompt_dir_real = os.path.realpath(self.voice_prompt_dir)
candidate = os.path.realpath(os.path.join(voice_prompt_dir_real, safe_name))
if os.path.commonpath([voice_prompt_dir_real, candidate]) != voice_prompt_dir_real:
raise web.HTTPBadRequest(reason="Invalid voice_prompt path")
requested_voice_prompt_path = candidate
# If the voice prompt file does not exist, find a valid (s0) voiceprompt file in the directory
if requested_voice_prompt_path is None or not os.path.exists(requested_voice_prompt_path):
raise FileNotFoundError(
Expand Down