Arbitrary code execution via eval() of a third-party model pack's train.log field in the WebUI
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 78/100
Direzione di ricerca
Leggi webui.py:1719-1726 in change_info_ e il collegamento di ckpt_path2.change in webui.py:2820-2822. Esegui le riproduzioni di train.log malevolo e del controllo negativo dell’issue, quindi verifica che il parsing rifiuti le espressioni eseguibili mentre i dati validi di model-info continuano ad aggiornare i selettori senza creare il file canary.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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
- 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.
- Start the WebUI: python webui.py --pycmd python3 --port 7897
- 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.
- 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.
- 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]
)
link:
- Lingua principale
- Python
- Stelle
- 38.8k
- Fork
- 5.3k
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di RVC-Project/Retrieval-based-Voice-Conversion-WebUI
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
RVC-Project/Retrieval-based-Voice-Conversion-WebUI#2863 · 1 commento · 2 reazioni ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
RVC-Project/Retrieval-based-Voice-Conversion-WebUI#2862 · 2 commenti ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
add git clone into READMEAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
RVC-Project/Retrieval-based-Voice-Conversion-WebUI#2831 · 1 commento ·
-
audio fieldAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
Tutte le issue di RVC-Project/Retrieval-based-Voice-Conversion-WebUI
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
eclipse-score/inc_someip_gateway#356 ·
I maintainer di solito rispondono entro 2 giorni
-
[BUG]: `GitHubRestAdapter.check_user_permission` and `has_write_access` raise `TypeError` (missing `params`), silently disabling the inactivity lifecycleForse già presa @tarunagnihotri534 l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
AOSSIE-Org/Gitcord-GithubDiscordBot#167 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
mihai-vlc/sublime-jsfmt#56 ·
-
comp/cli comp/plugins P2 type/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
NousResearch/hermes-agent#141917 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
riscv/riscv-opcodes#441 ·