Coordinated Disclosure Timeline
- 2025-03-14: Created an issue in the repository asking for a vulnerability contact.
- 2025-05-06: Commented again on the issue.
- 2025-06-16: GitHub Security Lab requests CVEs to these vulnerabilities due to our 90 day disclosure policy.
Summary
GPT-SoVITS is vulnerable to multiple unsafe deserializations, which lead to remote code execution.
Project
RVC-Boss/GPT-SoVITS
Tested Version
Details
Issue 1: unsafe deserialization in vr.py
AudioPre
(GHSL-2025-049
)
The model_choose
variable takes user input (e.g. a path to a model) and passes it to the uvr
function. In uvr
, a new instance of AudioPre
class is created with the model_path
attribute containing the aforementioned user input (here called locally model_name
). Note that in this step the .pth
extension is added to the path.
In the AudioPre
class, the user input, here called model_path
, is used to load the model on that path with torch.load
, which can lead to unsafe deserialization.
class AudioPre:
def __init__(self, agg, model_path, device, is_half, tta=False):
self.model_path = model_path
self.device = device
self.data = {
# Processing Options
"postprocess": False,
"tta": tta,
# Constants
"window_size": 512,
"agg": agg,
"high_end_process": "mirroring",
}
mp = ModelParameters("infer/lib/uvr5_pack/lib_v5/modelparams/4band_v2.json")
model = Nets.CascadedASPPNet(mp.param["bins"] * 2)
cpk = torch.load(model_path, map_location="cpu")
Impact
The issue can lead to remote code execution.
CWEs
- CWE-502: Deserialization of Untrusted Data
Issue 2: unsafe deserialization in vr.py
AudioPreDeEcho
(GHSL-2025-050
)
The model_choose
variable takes user input (e.g. a path to a model) and passes it to the uvr
function. In uvr
, a new instance of AudioPreDeEcho
class is created with the model_path
attribute containing the aforementioned user input (here called locally model_name
). Note that in this step the .pth
extension is added to the path.
In the AudioPreDeEcho
class, the user input, here called model_path
, is used to load the model on that path with torch.load
, which can lead to unsafe deserialization.
class AudioPreDeEcho:
def __init__(self, agg, model_path, device, is_half, tta=False):
self.model_path = model_path
self.device = device
self.data = {
# Processing Options
"postprocess": False,
"tta": tta,
# Constants
"window_size": 512,
"agg": agg,
"high_end_process": "mirroring",
}
mp = ModelParameters("%s/lib/lib_v5/modelparams/4band_v3.json"%parent_directory)
nout = 64 if "DeReverb" in model_path else 48
model = CascadedNet(mp.param["bins"] * 2, nout)
cpk = torch.load(model_path, map_location="cpu")
Impact
The issue can lead to remote code execution.
CWEs
-
CWE-502: Deserialization of Untrusted Data
Issue 3: unsafe deserialization in
bsroformer.py
(GHSL-2025-051
)
The model_choose
variable takes user input (e.g. a path to a model) and passes it to the uvr
function. In uvr
, a new instance of Roformer_Loader
class is created with the model_path
attribute containing the aformentioned user input (here called locally model_name
). Note that in this step the .ckpt
extension is added to the path.
In the Roformer_Loader
class, the user input, here called model_path
, is used to load the model on that path with torch.load
, which can lead to unsafe deserialization.
def __init__(self, model_path, config_path, device, is_half):
self.device = device
self.is_half = is_half
self.model_type = None
self.config = None
# snip
print("Detected model type: {}".format(self.model_type))
model = self.get_model_from_config()
state_dict = torch.load(model_path, map_location="cpu")
Impact
The issue can lead to remote code execution.
CWEs
- CWE-502: Deserialization of Untrusted Data
Issue 4: unsafe deserialization in inference_webui.py
(GHSL-2025-052
)
The GPT_dropdown
variable takes user input and passes it to the change_gpt_weights
function. In change_gpt_weights
, the user input, here gpt_path
is used to load a model with torch.load
, leading to unsafe deserialization.
def change_gpt_weights(gpt_path):
global hz, max_sec, t2s_model, config
hz = 50
dict_s1 = torch.load(gpt_path, map_location="cpu")
Impact
The issue can lead to remote code execution.
CWEs
- CWE-502: Deserialization of Untrusted Data
Issue 5: unsafe deserialization in process_ckpt.py
(GHSL-2025-053
)
The SoVITS_dropdown
variable takes user input and passes it to the load_sovits_new
function in process_ckpt.py
. In load_sovits_new
, the user input, here sovits_path
is used to load a model with torch.load
, leading to unsafe deserialization.
def load_sovits_new(sovits_path):
f=open(sovits_path,"rb")
meta=f.read(2)
if meta!="PK":
data = b'PK' + f.read()
bio = BytesIO()
bio.write(data)
bio.seek(0)
return torch.load(bio, map_location="cpu", weights_only=False)
return torch.load(sovits_path,map_location="cpu", weights_only=False)
Impact
The issue can lead to remote code execution.
CWEs
- CWE-502: Deserialization of Untrusted Data
CVE
- CVE-2025-49837 - GHSL-2025-049
- CVE-2025-49838 - GHSL-2025-050
- CVE-2025-49839 - GHSL-2025-051
- CVE-2025-49840 - GHSL-2025-052
- CVE-2025-49841 - GHSL-2025-053
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-2025-049
, GHSL-2025-050
, GHSL-2025-051
, GHSL-2025-052
, or GHSL-2025-053
in any communication regarding these issues.