Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Arbitrary code execution via eval() of a third-party model pack's train.log field in the WebUI

Abierto Apto para principiantes
#2,866 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
security

Línea de trabajo

Lee webui.py:1719-1726 en change_info_ y la conexión de ckpt_path2.change en webui.py:2820-2822. Ejecuta las reproducciones de train.log maliciosa y de control negativo del issue, y verifica después que el análisis rechaza expresiones ejecutables mientras los datos válidos de model-info siguen actualizando los selectores sin crear el archivo canary.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

1. Summary

RVC WebUI wires the change event of the model-path textbox to change_info_ (webui.py:2821). change_info_ reads the sidecar file train.log shipped next to the selected model, takes the last tab-separated field of the first line, and passes it straight to eval() (webui.py:1719-1726). Model packs usually come from third-party sharing (cloud drives, model sites), so this train.log is attacker-controlled untrusted input: with a completely benign .pth, a single line of log text is enough to execute arbitrary Python code with WebUI process privileges on the victim's machine.

2. Affected version / environment

Repository: RVC-Project/Retrieval-based-Voice-Conversion-WebUI; verification anchor: commit 81eed5e (webui.py:1715-1731 change_info_; webui.py:2821 .change wiring); latest release: tag 2.3.260718 and the current main branch (checked 2026-09-30) still contain the same code; history: tag 2.2.231006 (2023-10) already had the same eval in infer-web.py:754-761, so the flaw is at least ~2 years old; PoC environment: Docker official python:3.11-slim image (Python 3.11.16) with the project's own CPU dependency list requirments_cpu_py312.txt (gradio 3.14.0; torch 2.4.1+cpu); the WebUI listens on 0.0.0.0:7897 by default.

3. Steps to reproduce

  1. Build a model pack evil_model/ containing two files: G_23333.pth is a normal, benign small checkpoint (generated with torch.save, byte-identical to the negative control); the first line of train.log follows the project's own log format "%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s" with the last field (the message slot) replaced by the Python expression (import('pathlib').Path('/out/pwned_by_rvc_train_log_eval').write_text('MBE2E-CANARY-rvc-train-log-eval-v1\n', encoding='utf-8'), {'sample_rate': '48k', 'if_f0': 1, 'version': 'v2'})[1], which first writes a canary file and then returns the model-info dict, so the UI update completes normally without any error.
  2. Start the WebUI: python webui.py --pycmd python3 --port 7897
  3. Fire the same event a real user triggers: put the path evil_model/G_23333.pth into the "Path to Model" textbox of the checkpoint-extraction section (the .change event invokes change_info_); in the PoC the project's own Gradio queue API is used (/queue/join WebSocket, same protocol as the product frontend), submitting that path with fn_index pointing at the .change listener.
  4. Observe the server filesystem: /out/pwned_by_rvc_train_log_eval now exists with content "MBE2E-CANARY-rvc-train-log-eval-v1", while the UI shows no anomaly at all.
  5. Negative control: same directory layout and byte-identical .pth, but with the last train.log field replaced by the plain dict literal {'sample_rate': '48k', 'if_f0': 1, 'version': 'v2'}; repeat step 3 — it returns 48k/1/v2 and produces no file.

4. Expected behavior / Actual behavior

Expected: train.log is untrusted data carried inside a third-party model pack; parsing its field to prefill the sample-rate/if_f0/version selectors must never execute any code from it.
Actual: the field content is evaluated by eval(); the attacker's expression runs with WebUI process privileges, and because the payload returns a legitimate info dict the UI updates silently — no error, no warning.

5. Impact

  • Full arbitrary code execution with WebUI process privileges: file read/exfiltration, persistence, weight replacement, all possible.
  • The payload hides in "log text" while the .pth stays clean, so weight-based scanning and user intuition (people only look at the weights) both miss it; the expression returns a normal dict, so nothing is surfaced to the UI.
  • The trigger (selecting/pasting a model path in the WebUI) is the unavoidable step of loading community models; no training, no GPU, no extra interaction required.

6. Suggested fix

Replace the eval() at webui.py:1719 with a constrained parser: prefer ast.literal_eval(info_str), which accepts literals only and rejects any call or name lookup; treat parse failures as "no train.log info" (fall back to the UI defaults) instead of swallowing them into a traceback; the cleaner long-term option is a JSON convention (json.dumps on the writer side), fully dropping Python literal evaluation. Also consider warning the user when a model path with a sidecar train.log is loaded for the first time.

7. Additional context

  • Vulnerable code (webui.py:1719-1726, commit 81eed5e):
info = eval(
    read_text(
        ckpt_path.replace(os.path.basename(ckpt_path), "train.log")
    )
    .strip("\n")
    .split("\n")[0]
    .split("\t")[-1]
)
sr, f0 = info["sample_rate"], info["if_f0"]
  • Event wiring (webui.py:2820-2822):
ckpt_path2.change(
    change_info_, [ckpt_path2], [sr__, if_f0__, version_1]
)

rvc-train-log-eval-poc.zip

link:

https://github.com/3em0/cve_repo/blob/main/2026/Retrieval-based-Voice-Conversion-WebUI_Arbitrary_Code_Execution_via_eval()_of_Sidecar_train.log_in_WebUI_change_info_.md

Lenguaje dominante
Python
Estrellas
38.9k
Forks
5.3k
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de RVC-Project/Retrieval-based-Voice-Conversion-WebUI

Todos los issues de RVC-Project/Retrieval-based-Voice-Conversion-WebUI

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.