Coordinated Disclosure Timeline
- 2024-12-11: Reported the vulnerabilities via PVR.
- 2025-01-07: Followed up asking if the vulnerabilities have been fixed.
- 2025-01-22: Reached out again.
- 2023-01-27: The maintainer commented on an issue in another repository, and from there I asked them to check PVR.
- 2025-01-28: Received a reply in PVR asking about the impact. Explained the impact of GHSL-2024-354 and GHSL-2024-341 through GHSL-2024-353.
- 2025-02-01: The unsafe deserialization vulnerabilities (GHSL-2024-345 through GHSL-2024-348) were issued a fix.
- 2025-02-03: Reached out explaining the next steps in the disclosure process.
- 2025-02-10: Reached out with a reminder about the 90d disclosure deadline.
- 2025-03-07: Gave a notice about the deadline.
- 2025-03-10: Final notice about the deadline, and heads-up that details will be published by the end of the week.
Summary
Applio 3.2.7 is vulnerable to unsafe deserialization, SSRFs and arbitrary file writes, arbitrary file read and arbitrary file removal.
Project
Applio
Tested Version
Details
Issue 1: SSRF and file write in model_download.py line 143 (GHSL-2024-341)
These endpoints take a user-supplied URL:
- download.py on line 194
- routes.py which later is used to make an HTTP GET request to arbitrary destinations in model_download.py on line 143 and then download arbitrary files from the URL on lines 147-148, which leads to blind server-side request forgery and file write.
Similar issues exist for GHSL-2024-342 and GHSL-2024-343.
model_download.py
elif "cdn.discordapp.com" in url:
file = requests.get(url)
os.chdir(zips_path)
if file.status_code == 200:
name = url.split("/")
with open(os.path.join(name[-1]), "wb") as newfile:
newfile.write(file.content)
This issue was found with help of CodeQL SSRF query.
Impact
The blind server-side request forgery allows for sending requests on behalf of applio server and can be leveraged to probe for other vulnerabilities on the server itself or on other back-end systems on the internal network, that the applio server can reach.
The blind SSRF can be coupled with the arbitrary file read GHSL-2024-351, to read files from hosts on the internal network, that the applio server can reach, which would make it a full SSRF.
The file write allows for writing files on the server, which can be coupled with other vulnerabilities, for example one of the unsafe deserialisations, to achieve remote code execution on the applio server.
Issue 2: SSRF and file write in model_download.py line 156 (GHSL-2024-342)
Similarly to GHSL-2024-341 and GHSL-2024-343, the two endpoints take a user-supplied URL:
- download.py on line 194
- routes.py which later is used to make an HTTP GET request to arbitrary destinations in model_download.py on line 156 and then download arbitrary files from the URL on lines 169-171, which leads to blind server-side request forgery and file write.
elif "/blob/" in url or "/resolve/" in url:
os.chdir(zips_path)
if "/blob/" in url:
url = url.replace("/blob/", "/resolve/")
response = requests.get(url, stream=True)
Impact
The blind server-side request forgery allows for sending requests on behalf of applio server and can be leveraged to probe for other vulnerabilities on the server itself or on other back-end systems on the internal network, that the applio server can reach.
The file write allows for writing files on the server, which can be coupled with other vulnerabilities, for example one of the unsafe deserialisations, to achieve remote code execution on the applio server.
Issue 3: SSRF and file write in model_download.py line 240 (GHSL-2024-343)
Similarly to GHSL-2024-341 and GHSL-2024-342, the two endpoints take a user-supplied URL:
- download.py on line 194
- routes.py which later is used to make an HTTP GET request to arbitrary destinations in model_download.py on line 240 and download arbitrary files, which leads to blind server-side request forgery and file write.
Similar issues exist for GHSL-2024-341 and GHSL-2024-342.
model_download.py
else:
try:
os.chdir(zips_path)
wget.download(url)
This issue was found with help of CodeQL SSRF query.
Impact
The blind server-side request forgery allows for sending requests on behalf of applio server and can be leveraged to probe for other vulnerabilities on the server itself or on other back-end systems on the internal network, that the applio server can reach.
The blind SSRF can be coupled with the arbitrary file read GHSL-2024-351, to read files from hosts on the internal network, that the applio server can reach, which would make it a full SSRF.
The file write allows for writing files on the server, which can be coupled with other vulnerabilities, for example one of the unsafe deserialisations, to achieve remote code execution on the applio server.
Issue 4: SSRF in model_download.py line 195 (GHSL-2024-344)
Similarly to the above issues, the two endpoints take a user-supplied URL:
- download.py on line 194
- routes.py which later is used to make an HTTP GET request to arbitrary destinations in model_download.py on line 195 which leads to blind server-side request forgery.
elif "/tree/main" in url:
os.chdir(zips_path)
response = requests.get(url)
This issue was found with help of CodeQL SSRF query.
Impact
The blind server-side request forgery allows for sending requests on behalf of applio server and can be leveraged to probe for other vulnerabilities on the server itself or on other back-end systems on the internal network, that the applio server can reach.
The blind SSRF can be coupled with the arbitrary file read GHSL-2024-351, to read files from hosts on the internal network, that the applio server can reach, which would make it a full SSRF.
Issue 5: Unsafe deserialization in infer.py (GHSL-2024-345)
model_filein inference.py as well asmodel_filein tts.py take user-supplied input (e.g. a path to a model) and pass that value to therun_infer_scriptand later toconvert_audioand thenget_vcfunction, which loads that model withtorch.loadin infer.py line 464, which is vulnerable to unsafe deserialization.
Impact
The issue can lead to remote code execution.
Issue 6: Unsafe deserialization in model_blender.py line 20 and 21 (GHSL-2024-346)
model_fusion_a and model_fusion_b from voice_blender.py take user-supplied input (e.g. a path to a model) and pass that value to the run_model_blender_script and later to model_blender function, which loads these two models with torch.load in `model_blender.py on lines 20-21, which is vulnerable to unsafe deserialization.
Impact
The issue can lead to remote code execution.
Issue 7: Unsafe deserialization in model_information.py (GHSL-2024-347)
model_name in model_information.py
takes user-supplied input (e.g. a path to a model) and pass that value to the run_model_information_script and later to model_information function, which loads that model with torch.load in rvc/train/process/model_information.py on line 16, which is vulnerable to unsafe deserialization.
Impact
The issue can lead to remote code execution.
Issue 8: Unsafe deserialization in inference.py (GHSL-2024-348)
model_filein inference.py as well asmodel_filein tts.py take user-supplied input (e.g. a path to a model) and pass that value to thechange_choicesand later toget_speakers_idfunction, which loads that model withtorch.loadin inference.py line 325, which is vulnerable to unsafe deserialization.
Impact
The issue can lead to remote code execution.
Issue 9: Arbitrary file write in inference.py (GHSL-2024-349)
The three endpoints:
folder_name_input,bin_file_upload,config_file_uploadininference.pylines 989-1002folder_name_input_batch,bin_file_upload_batchandconfig_file_upload_batchininference.pyline 1632-45folder_name_input,bin_file_upload,config_file_uploadintts.pylines 309-322
take arbitrary user input in folder_name_input and files in bin_file_upload, config_file_upload and pass that input to create_folder_and_move_files function in inference.py. folder_name_input is used to construct a path on line 295
and then copy the uploaded files on lines 300 and 304. There is no check if the file is copied the expected, static custom_embedder_root path, which allows attackers to write arbitrary file on applio server, as long the user running the application has write access to a given path.
def create_folder_and_move_files(folder_name, bin_file, config_file):
if not folder_name:
return "Folder name must not be empty."
folder_name = os.path.join(custom_embedder_root, folder_name)
os.makedirs(folder_name, exist_ok=True)
if bin_file:
bin_file_path = os.path.join(folder_name, os.path.basename(bin_file))
shutil.copy(bin_file, bin_file_path)
if config_file:
config_file_path = os.path.join(folder_name, os.path.basename(config_file))
shutil.copy(config_file, config_file_path)
This issue was found with help of CodeQL path injection query.
Impact
This issue may lead to writing arbitrary files on the applio server. It can also be used in conjunction with any of the unsafe deserialisations to achieve remote code execution.
Issue 10: Arbitrary file write in train.py (GHSL-2024-350)
This issue is very similar to GHSL-2024-349. The code for the two issues is almost the same, but the happen in different files.
folder_name_input, bin_file_upload, config_file_upload in tabs/train/train.py take arbitrary user input in folder_name_input and files in bin_file_upload, config_file_upload and pass that input to create_folder_and_move_files function in tabs/train/train.py. folder_name_input is used to construct a path on line 295
and then copy the uploaded files. There is no check if the file is copied the expected, static custom_embedder_root path, which allows attackers to write arbitrary file on applio server, as long the user running the application has write access to a given path.
def create_folder_and_move_files(folder_name, bin_file, config_file):
if not folder_name:
return "Folder name must not be empty."
folder_name = os.path.join(custom_embedder_root, folder_name)
os.makedirs(folder_name, exist_ok=True)
if bin_file:
bin_file_path = os.path.join(folder_name, os.path.basename(bin_file))
shutil.copy(bin_file, bin_file_path)
if config_file:
config_file_path = os.path.join(folder_name, os.path.basename(config_file))
shutil.copy(config_file, config_file_path)
This issue was found with help of CodeQL path injection query.
Impact
This issue may lead to writing arbitrary files on the applio server. It can also be used in conjunction with any of the unsafe deserialisations to achieve remote code execution.
Issue 11: Arbitrary file read in train.py export_pth function (GHSL-2024-351)
pth_dropdown_export in tabs/train/train.py takes arbitrary user input and passes it to export_pth function, which checks that the file exists, and returns it to user. Since there are no restrictions on which files it returns, this leads to arbitrary file read on files on the applio server.
def export_pth(pth_path):
if pth_path and os.path.exists(pth_path):
return pth_path
This issue was found with help of CodeQL path injection query.
Impact
This issue may lead to reading arbitrary files on the applio server. It can also be used in conjunction with any of the blind SSRF to read files from servers on the internal network that the applio server has access to.
Issue 12: Arbitrary file read in train.py export_index function (GHSL-2024-352)
index_dropdown_export in tabs/train/train.py takes arbitrary user input and passes it to export_index function, which checks that the file exists, and returns it to user. Since there are no restrictions on which files it returns, this leads to arbitrary file read on files on the applio server.
def export_index(index_path):
if index_path and os.path.exists(index_path):
return index_path
return None
This issue was found with help of CodeQL path injection query.
Impact
This issue may lead to reading arbitrary files on the applio server. It can also be used in conjunction with any of the blind SSRF to read files from servers on the internal network that the applio server has access to.
Issue 13: Arbitrary file removal in core.py (GHSL-2024-353)
output_tts_path in tts.py takes arbitrary user input and passes it to run_tts_script function in core.py, which checks if the path in output_tts_path exists, and if yes, removes that path, which leads to arbitrary file removal.
if os.path.exists(output_tts_path):
os.remove(output_tts_path)
Impact
This issue may lead to reading arbitrary files on the applio server. It can also be used in conjunction with any of the blind SSRF to read files from servers on the internal network that the applio server has access to.
CVE
- CVE-2025-27774 - GHSL-2024-341
- CVE-2025-27775 - GHSL-2024-342
- CVE-2025-27776 - GHSL-2024-343
- CVE-2025-27777 - GHSL-2024-344
- CVE-2025-27778 - GHSL-2024-345
- CVE-2025-27779 - GHSL-2024-346
- CVE-2025-27780 - GHSL-2024-347
- CVE-2025-27781 - GHSL-2024-348
- CVE-2025-27782 - GHSL-2024-349
- CVE-2025-27783 - GHSL-2024-350
- CVE-2025-27784 - GHSL-2024-351
- CVE-2025-27785 - GHSL-2024-352
- CVE-2025-27786 - GHSL-2024-353
Credit
These issues were discovered and reported by GHSL team member @sylwia-budzynska (Sylwia Budzynska).
Contact
You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2024-341, GHSL-2024-342, GHSL-2024-343, GHSL-2024-344, GHSL-2024-345, GHSL-2024-346, GHSL-2024-347, GHSL-2024-348, GHSL-2024-349, GHSL-2024-350, GHSL-2024-351, GHSL-2024-352, or GHSL-2024-353 in any communication regarding these issues.