You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Security] Model load-time code execution: ONNX metadata strings evaluated with eval() in the vendored ultralytics copy (models/MobileSAMv2) #145
This repository vendors ultralytics8.0.120 inside a vendored sub-project (models/MobileSAMv2/ultralytics/…), and that copy still parses ONNX model metadata with eval(). Loading an untrusted .onnx therefore executes attacker-chosen Python in the loading process — before any inference, and before the pickle-free path that leads people to choose ONNX in the first place.
file sha256 55a5363f49f0a63d18d07c01264fabd7e3fab7cfbdeb9125e5bf43d642b0c4d8 (byte-identical to the file CASIA-LMC-Lab/FastSAM ships at the same 8.0.120 vintage)
Steps to reproduce
Build a minimal .onnx whose metadata_props carries a constant-only expression for imgsz (for example "7*191").
Load it through the vendored code: AutoBackend(weights="model.onnx") — the library's ordinary action for a model file.
The expression runs while the constructor executes, and imgsz comes back as [640, 640] — a value only eval() of the stored string could produce.
Expected behavior
metadata_props is inert data; imgsz / names / kpt_shape are parsed, not executed.
Actual behavior
The stored strings are evaluated with the module globals and unrestricted builtins. Between the read at :132 and the eval at :278 there is no allow-list, no regex, no restricted builtins and no try/except. imgsz, names and kpt_shape are exactly the keys a genuine exported model carries, and ONNX Runtime places no constraint on metadata_props.
How it was verified
Code-level: the source and sink lines above were re-read live at this repository's default branch HEAD on 2026-09-29. Execution-level: the exact bytes this repository vendors were executed on 2026-09-29 — the official PyPI ultralytics8.0.120 wheel, whose nn/autobackend.py is byte-identical to the vendored file (same sha256 55a5363f…), was driven through AutoBackend(weights=…) with a harmless sentinel expression in the metadata (it only writes one inert marker file) and a benign-metadata negative control: the marker appears for the attack artifact, never for the control. A sibling vendored copy of the same lineage (iMoonLab/yolov13, 8.3.63) was additionally driven end-to-end through the product's own yolo predict CLI. No exploit string is included here; the sentinels are harmless integer constants — no network, no shell, no persistence.
Impact
Arbitrary code execution with the privileges of the loading process — anything that process can read or write (datasets, checkpoints, hub tokens, cloud credentials), plus the ability to terminate or hang it.
Suggested fix
Apply the one-line upstream fix at models/MobileSAMv2/ultralytics/nn/autobackend.py:278, or resync the vendored sub-project to >= 8.3.234. ast is already imported in the file:
Activity