#1306·F5-TTS

[Vulnerability] OS command injection in finetune_gradio.py start_training() via shell=True

Author: WHJ125Created Jul 13, 2026Updated Aug 21, 2026
Labelsbug

Checks

  • This template is only for bug reports, usage problems go with 'Help Wanted'.
  • I have thoroughly reviewed the project documentation but couldn't find information to solve my problem.
  • I have searched for existing issues, including closed ones, and couldn't find a solution.
  • I am using English to submit this issue to facilitate community communication.

Environment Details

  • OS: Linux container
  • User privileges: root inside the container
  • Python: 3.11
  • Environment manager: Miniconda
  • Conda environment: f5-tts
  • F5-TTS installation: local editable installation from the cloned repository
  • F5-TTS source path:
/hdd2/ul7ear/F5-TTS
  • Affected source file:
/hdd2/ul7ear/F5-TTS/src/f5_tts/train/finetune_gradio.py
  • Gradio application URL:
http://127.0.0.1:7861/
  • Environment information
Python: 3.11.15 (main, Jun 11 2026, 15:20:16) [GCC 14.3.0]
Python executable: /hdd2/ul7ear/miniconda3/envs/f5-tts/bin/python
Gradio: 5.49.1
PyTorch: 2.13.0+cu130
PyTorch CUDA: 13.0
CUDA available: False
F5-TTS module: None
git -C /hdd2/ul7ear/F5-TTS rev-parse HEAD
git -C /hdd2/ul7ear/F5-TTS status --short
91f499635cb4f8b8a926e83f1839f5338bc2ef87

Steps to Reproduce

The start_training() function constructs an accelerate launch command by concatenating values received from the Gradio interface into a single string.

For example, the pretrained checkpoint value is added as follows:

python
if file_checkpoint_train != "":
    cmd += f' --pretrain "{file_checkpoint_train}"'

The command is then executed through an operating-system shell:

python
training_process = subprocess.Popen(cmd, shell=True)

The streaming branch also uses:

python
training_process = subprocess.Popen(
    cmd,
    shell=True,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True,
    bufsize=1,
    env=env,
)

Because POSIX shells evaluate command substitution expressions such as $(...) inside double quotes, the checkpoint-path field can execute an operating-system command.

1. Create a test project

In the Gradio interface, create a project named:

security_poc

This creates a project similar to:

security_poc_pinyin

Create the raw.arrow file required by start_training():

bash
touch /hdd2/ul7ear/F5-TTS/data/security_poc_pinyin/raw.arrow

The file does not need to contain a valid dataset for this reproduction. The shell command is evaluated before the training script processes the dataset or checkpoint.

2. Remove any previous marker

bash
rm -f /tmp/f5tts_cmd_injection_poc

3. Open the Train Model tab

Select the following project:

security_poc_pinyin

Enable Finetune.

4. Enter the following value in “Path to the Pretrained Checkpoint”

$(printf 'F5TTS_POC\n' > /tmp/f5tts_cmd_injection_poc)

This payload only creates a local marker file under /tmp. It does not access secrets, create a network connection, or modify application files.

Image

5. Click “Start Training”

The application prints a command similar to:

accelerate launch "/hdd2/ul7e


ar/F5-TTS/src/f5_tts/train/finetune_cli.py" --exp_name F5TTS_v1_Base --learning_rate 1e-05 --batch_size_per_gpu 3200 --batch_size_type frame --max_samples 64 --grad_accumulation_steps 1 --max_grad_norm 1 --epochs 1 --num_warmup_updates 10 --save_per_updates 10 --keep_last_n_checkpoints 0 --last_per_updates 10 --dataset_name security_poc --finetune --pretrain "$(printf F5TTS_POC > /tmp/f5tts_cmd_injection_poc)" --tokenizer pinyin --log_samples

6. Check the marker file

bash
ls -l /tmp/f5tts_cmd_injection_poc
cat /tmp/f5tts_cmd_injection_poc

Observed contents:

F5TTS_POC
Image

✔️ Expected Behavior

Values entered into file-path fields should be passed to the training process as literal command-line arguments.

Shell syntax such as the following should not be interpreted or executed:

$()
;
&&
|
>
`

❌ Actual Behavior

The checkpoint-path value is concatenated into a shell command string and executed using:

python
subprocess.Popen(cmd, shell=True)

As a result, command substitution contained in the checkpoint-path field is evaluated by the operating-system shell.

The non-destructive reproduction successfully created:

/tmp/f5tts_cmd_injection_poc

This confirms arbitrary command execution with the privileges of the F5-TTS Gradio process.

In the reproduced environment, the process was running as root inside a container. Therefore, the injected command executed with root privileges inside that container.

The security impact depends on deployment:

  • On a trusted localhost-only deployment, an attacker requires access to the local Gradio interface or API.
  • If the application is bound to 0.0.0.0, shared through a Gradio public link, published from a container, or exposed through an unauthenticated reverse proxy, this may become unauthenticated remote command execution.
  • An attacker could potentially read or modify accessible model files, datasets, environment variables, API tokens, and host-mounted files.
  • Available CPU and GPU resources could also be abused.

Likely classification:

CWE-78: Improper Neutralization of Special Elements used in an OS Command