Coordinated Disclosure Timeline

Summary

GPT-SoVITS is vulnerable to multiple unsafe deserializations, which lead to remote code execution.

Project

RVC-Boss/GPT-SoVITS

Tested Version

20250228v3

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

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

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

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

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

CVE

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.