RAXE-2026-048 HIGH CVSS 8.6 v3.1 S3

ONNX Model Deserialization Attribute Injection via setattr()

Supply Chain 2026-04-03 M. Hirani TLP:GREEN

Executive Summary

The ExternalDataInfo class in ONNX used Python's built-in setattr() to populate object state directly from key-value pairs parsed out of .onnx model files, with no allowlist of valid attribute names applied before the call. Any party who can supply a model file to a target pipeline can exploit this to cause a deterministic out-of-memory crash (the primary risk), manipulate file-read offsets to access unintended data regions, or inject Python dunder attributes to corrupt object type state. The vulnerability is fixed in ONNX 1.21.0, available on PyPI. Organisations that load ONNX models from external or partially-trusted sources should upgrade immediately.

This is RAXE's second finding against the ONNX package this quarter. RAXE-2026-039 (CVE-2026-28500) covered a silent security-warning bypass in the ONNX Hub download client; this finding is an independent vulnerability in the model-parsing subsystem. CVE-2026-34445 is resolved by upgrading to onnx >= 1.21.0. Note: CVE-2026-28500 (RAXE-2026-039) does not yet have a listed patched version in its GHSA (GHSA-hqmj-h5c6-369m lists patched versions as "None"); the fix was implemented by removing the affected feature rather than through a versioned patch. Organisations should verify independently that their onnx version addresses both CVEs.

Severity: 8.6 HIGH. The high availability impact (deterministic OOM crash) drives the score. Confidentiality and integrity impacts are low. This finding is not assessed as critical.


Vulnerability Overview

Attribute Detail
Vulnerability class CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
Additional CWEs CWE-20 (Improper Input Validation), CWE-400 (Uncontrolled Resource Consumption)
Root cause Unconstrained setattr(self, key, value) in ExternalDataInfo — no key allowlist
Attack surface Any application that calls onnx.load() on an externally sourced model file
Affected versions onnx <= 1.20.1 (all releases prior to the fix)
Fixed version onnx >= 1.21.0
Fix commit e30c6935d67cc3eca2fa284e37248e7c0036c46b (PR #7751)
Reporter ZeroXJacks (GitHub), credited in GHSA-538c-55jv-c5g9
Published NVD: 2026-04-01T18:16:30Z; GHSA: 2026-04-01T21:10:52Z

Sources: GHSA-538c-55jv-c5g9 (https://github.com/advisories/GHSA-538c-55jv-c5g9); NVD CVE-2026-34445 (https://nvd.nist.gov/vuln/detail/CVE-2026-34445).

ONNX model files use Protocol Buffers for serialisation. Tensor data stored outside the model binary is described by ExternalDataInfo objects, each holding metadata fields (notably length, offset, location) parsed from the model's external_data entries. In the vulnerable code path, the key names from these entries were passed directly to setattr() with no validation. Because Python's setattr() accepts any string as an attribute name, an adversarially crafted model file can inject arbitrary attribute values — including out-of-range numeric fields and Python dunder attributes — into the ExternalDataInfo object at load time.

Fix commit e30c6935d67cc3eca2fa284e37248e7c0036c46b replaced the unconstrained setattr() pattern with explicit attribute validation. Source: GHSA-538c-55jv-c5g9, PR #7751 (https://github.com/onnx/onnx/pull/7751).


Technical Analysis

Attack Flow

Attacker                     Distribution Channel            Target Pipeline
   |                                  |                             |
   |  1. Craft .onnx model file       |                             |
   |     with adversarial             |                             |
   |     external_data metadata       |                             |
   |--------------------------------->|                             |
   |                                  |  2. Deliver model file      |
   |                                  |---------------------------->|
   |                                  |                             |
   |                                  |      3. onnx.load() called  |
   |                                  |      ExternalDataInfo reads |
   |                                  |      external_data entries  |
   |                                  |                             |
   |                                  |      4. setattr(self, key,  |
   |                                  |         value) — no         |
   |                                  |         allowlist check     |
   |                                  |                             |
   |                                  |      5. Attacker-controlled |
   |                                  |         attribute value is  |
   |                                  |         applied to object   |
   |                                  |                             |
   |                                  |      VECTOR 1: OOM crash    |
   |                                  |      VECTOR 2: Offset bypass|
   |                                  |      VECTOR 3: Type corrupt |

Distribution channel may be a public model hub, a dependency mirror, a partner API, or a direct file upload. No authentication or special privileges are required of the attacker — only the ability to deliver a file.

Vector 1: OOM Denial of Service via length

Source: GHSA-538c-55jv-c5g9 — "An attacker can set the length property to a massive number like 9 petabytes. When the system tries to load the model, it attempts to allocate all that RAM at once, causing the server to crash or freeze Out of Memory."

The length field in ExternalDataInfo tells the runtime how many bytes to read from the external tensor data file. In the vulnerable code path, an attacker-supplied length value (e.g., 9000000000000000 — approximately 9 petabytes) is applied to the object via setattr() without any bounds check. When the runtime subsequently attempts to size a buffer allocation using this value, it requests a contiguous allocation of the attacker-controlled size. The Python process raises MemoryError or is killed by the OS OOM killer. The crash is deterministic: every load attempt against the crafted model triggers it.

Observable indicators: process termination with MemoryError, OS OOM kill (exit code 137 on Linux), or service unavailability following a model load request. No inference output is returned.

This vector drives the A:H (availability: high) component of the CVSS vector and is the primary operational risk. Attack complexity is low: knowledge of the ONNX protobuf schema is sufficient to construct the payload.

Vector 2: File-Read Bypass via offset

Source: GHSA-538c-55jv-c5g9 — "By setting a negative offset -1, an attacker can trick the system into reading parts of a file it wasn't supposed to touch."

The offset field specifies where within the external data file to begin reading tensor bytes. The ONNX specification requires this to be a non-negative integer. In the vulnerable code path, setting offset to a negative integer (e.g., -1) via setattr() causes the runtime to seek to an out-of-bounds position within the external data file. The read proceeds from an unintended file region, incorporating adjacent file content into the tensor data returned to the application. (RAXE assessment based on GHSA-538c-55jv-c5g9.)

Unlike the OOM crash, this vector may not produce a visible exception — the read may succeed silently with incorrect data, making it harder to detect at runtime. Observable indicators are anomalous file access patterns (negative-offset lseek syscalls) and garbled or incorrect tensor values in model output.

This vector accounts for the C:L (confidentiality: low) and I:L (integrity: low) components of the CVSS vector.

Vector 3: Type Corruption via __class__

Source: GHSA-538c-55jv-c5g9 — "Attackers can even inject 'dunder' attributes like __class__ to change the object's type entirely, which could lead to more complex exploits." (GHSA-538c-55jv-c5g9)

Python's setattr() does not restrict attribute names to those defined in the class. Injecting __class__ as a key in the external_data metadata causes setattr() to attempt to assign the supplied value to the ExternalDataInfo object's __class__ slot, altering the object's apparent type at runtime if the assignment succeeds. (RAXE assessment based on GHSA-538c-55jv-c5g9.) The GHSA advisory notes that this "could lead to more complex exploits" but does not describe a complete exploit chain.

RAXE assessment: No weaponised code execution path via this vector has been publicly demonstrated as of 2026-04-03. Python raises TypeError when __class__ is assigned an incompatible heap type, which constrains the practical reach of this vector without additional preconditions. This vector supports the I:L CVSS component; it does not currently support a re-evaluation to I:H absent a demonstrated exploit chain. See KAC section for stated assumptions.

Observable indicators: TypeError: __class__ assignment only supported for mutable types in Python application logs, in an onnx loading context.


Impact Assessment

CVSS Metric Value Driving Attack Vector
Attack Vector Network (AV:N) Model files are distributed and loaded over networks
Attack Complexity Low (AC:L) No special conditions; crafting a malicious .onnx file requires only knowledge of the protobuf schema
Privileges Required None (PR:N) Any party able to supply a model to the target is sufficient
User Interaction None (UI:N) The vulnerability triggers on model load, not on user action
Confidentiality Low (C:L) Vector 2: negative offset may expose adjacent file bytes
Integrity Low (I:L) Vector 3: object-state corruption; no controlled write primitive demonstrated
Availability High (A:H) Vector 1: OOM DoS via crafted length value is deterministic and trivially achieved

Overall CVSS: 8.6 HIGH. Severity label: HIGH. Not critical — the availability impact dominates; confidentiality and integrity impacts are assessed as low based on currently available public information.

The attack scenario of greatest operational concern is an ML inference service that accepts externally sourced model files. A supplier-side compromise, a malicious model repository, or a social-engineering lure can all serve as the delivery channel. The ONNX specification provides no runtime trust or signing mechanism for model provenance; the fix must be applied at the library level.


NVD Analysis Status Note

NVD status for CVE-2026-34445 is "Undergoing Analysis" as of 2026-04-03. NVD has not yet completed its own analysis of this CVE. The CVSS score of 8.6 HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H) is the CNA-submitted score as recorded in the NVD entry — it is not the result of NVD's independent assessment.

The fact-check for this finding confirms the metadata CVSS (8.6) matches the score in the NVD response (delta 0.0). However, because NVD's analysis is not yet complete, the score may be revised when NVD completes enrichment. RAXE will update this advisory if the score changes materially once analysis is complete.

Source: NVD CVE-2026-34445 (https://nvd.nist.gov/vuln/detail/CVE-2026-34445); RAXE fact-check report validation/fact-check-2026-04-03.json.


Exploitation Context

Metric Value Source
EPSS Score 0.0004 (0.04%) FIRST EPSS API, 2026-04-03
EPSS Percentile 12th FIRST EPSS API, 2026-04-03
Active Exploitation Observed No RAXE assessment, 2026-04-03
Public PoC Available No RAXE assessment, 2026-04-03
NVD Published 2026-04-01T18:16:30Z NVD
GHSA Published 2026-04-01T21:10:52Z GitHub Security Advisory

Source: FIRST EPSS API (https://api.first.org/data/v1/epss?cve=CVE-2026-34445).

The EPSS score of 0.04% indicates a low modelled probability of exploitation in the next 30 days (FIRST.org), consistent with a newly-disclosed vulnerability for which no public proof-of-concept exploit has been released. The 12th percentile position means roughly 88% of CVEs in the EPSS corpus carry a higher exploitation probability score at this point in time.

Remediation urgency is not reduced by the low EPSS. The primary attack path (OOM DoS via crafted length field) requires minimal attacker skill: knowledge of the ONNX protobuf schema is sufficient to construct the payload. The fix has been available since onnx 1.21.0 was published on PyPI. There is no technical barrier to upgrading.

The pattern of low EPSS combined with a readily constructable DoS primitive is characteristic of vulnerabilities in infrastructure libraries: mass exploitation does not occur immediately, but targeted use against specific ML inference infrastructure is feasible well before the EPSS score rises. (RAXE assessment.) Organisations with externally-facing model inference endpoints should treat this as a higher-priority item than the raw percentile implies.


ML Supply Chain Context

This finding is representative of a vulnerability class that is specific to the design patterns of ML model interchange. Loading untrusted ONNX models is a routine operation in ML pipelines: model files are downloaded from public model hubs, shared between teams, received from third-party integrators, and accepted as user-provided inputs. In each of these scenarios the model file is treated as passive data, yet the ONNX loading code path executes the model's metadata as instructions. The ExternalDataInfo vulnerability demonstrates that this implicit trust is not warranted: a structurally valid .onnx file that would pass format validation can carry adversarial payloads in its metadata fields. (RAXE assessment.)

Unlike generic software vulnerabilities such as path traversal or SQL injection, attribute injection via model deserialisation is created by the design patterns of ML interchange formats. The external_data field exists because large model tensors are stored outside the model binary for efficiency. The metadata that describes that external data is parsed and applied to Python objects at load time. Treating key names as trusted inputs to setattr() is the specific design choice that created the vulnerability surface.

The combination of this finding with RAXE-2026-039 (CVE-2026-28500, ONNX Hub silent warning bypass) illustrates a pattern across the ONNX ecosystem: both vulnerabilities exploit the assumption that model files and model acquisition channels are inert and trustworthy. RAXE-2026-039 targets the model-acquisition path; this finding targets the model-parsing path. They are independent code paths and independent CVEs. Organisations that remediated RAXE-2026-039 remain exposed to this finding unless they have also upgraded to onnx >= 1.21.0.

The strategic implication is not unique to ONNX: any ML model interchange format that applies metadata from model files to runtime objects without input validation creates an equivalent attack surface. The ONNX ecosystem is the largest target because of its broad adoption, but the vulnerability class extends to any framework that uses a similar loading pattern.


Detection Guidance

RAXE has produced four YARA rules and two Sigma rules for this finding. The files are: - detection/onnx-setattr-injection.yar (YARA-001 through YARA-004) - detection/onnx-setattr-injection.yml (Sigma SIGMA-001, SIGMA-002)

YARA rules are the stronger detection surface for this finding. The adversarial payload resides in the model file's external_data metadata fields, which are directly inspectable in the binary at rest — before the model is loaded. YARA scanning of model files at ingest provides pre-execution detection with no process telemetry required.

YARA Coverage

Rule ID Lane Vector Description
RAXE-2026-048-YARA-001 2 — Vulnerability-Informed Vector 1 OOM DoS: length key paired with a numeric value of 10+ digits (> 1 GB). Legitimate external data length values in this range are uncommon; the advisory example is 16 digits (~9 PB).
RAXE-2026-048-YARA-002 1 — High-Fidelity Vector 2 File-read bypass: offset key paired with a negative numeric string. Negative offset values are never legitimate in ONNX external data metadata; zero false positives expected on well-formed models.
RAXE-2026-048-YARA-003 2 — Vulnerability-Informed Vector 3 Dunder injection: presence of Python dunder attribute names (__class__, __dict__, __init__, __module__, __bases__, __subclasses__, __mro__, __reduce__, __reduce_ex__) as strings in the ONNX file.
RAXE-2026-048-YARA-004 1 — High-Fidelity (Composite) Vectors 1+2, 1+3, or 2+3 Composite: two or more adversarial patterns in the same file. A file matching multiple vectors is highly anomalous; treat all YARA-004 matches as high-priority pending manual review.

All four YARA rules include a private ONNX_File_Magic anchor that checks for the ai.onnx domain string, reducing false positives when scanning mixed-type file corpora.

Escalation priority: YARA-004 (Composite) > YARA-002 (Negative offset) > YARA-001 (OOM length) > YARA-003 (Dunder injection).

Sigma Coverage

Rule ID Lane Vector Description
SIGMA-RAXE-2026-048-001 2 — Vulnerability-Informed Vector 1 Python process OOM crash after ONNX model loading: kernel OOM-kill messages (Out of memory, Killed process) correlated with Python process names, or MemoryError in application logs with onnx context strings.
SIGMA-RAXE-2026-048-002 2/3 Vectors 2 and 3 Anomalous file access or TypeError during ONNX model loading: negative-offset lseek syscall in a Python process loading an .onnx file (Sub-rule A, Lane 2); or TypeError: __class__ assignment in application logs with onnx context (Sub-rule B, Lane 3).

Both Sigma rules are marked status: experimental. Sigma is the secondary detection surface: the behavioural indicators become observable at or after model load time, compared to YARA which operates on the file at rest.

Deployment Recommendations

Scan targets for YARA rules: - Model file staging areas where ONNX models are received from external sources before loading (e.g., model hubs, S3 buckets, NFS shares, upload endpoints). Scan on ingest. - CI/CD pipelines: scan any .onnx model committed to source control or fetched from a registry during build or test steps. - Inference server model stores: periodic scanning of the on-disk model repository used by inference services. - Container images that embed .onnx model files: scan before deployment.

Patching the library does not remove adversarial payloads from malicious model files already on disk. Malicious models identified by YARA scanning must be quarantined or deleted independently of the onnx upgrade.


Remediation

Immediate (now — 7 days)

Upgrade onnx to >= 1.21.0. This is the definitive fix. The patched release is available on PyPI (https://pypi.org/project/onnx/1.21.0/).

Verify the currently installed version:

pip show onnx

Upgrade:

pip install --upgrade onnx

Confirm the fix is in place by checking that the installed version is 1.21.0 or later. Fix commit: e30c6935d67cc3eca2fa284e37248e7c0036c46b, PR #7751.

Audit model-loading code paths. Identify all locations in your codebase where .onnx files are loaded and confirm they use a patched version of the library. Pay particular attention to inference services, model evaluation pipelines, and any endpoint that accepts user-supplied model files.

Near-term (30 days)

Enforce model provenance controls. Before loading any ONNX model from an external source, verify its cryptographic hash against a known-good manifest or a trusted registry entry. The ONNX specification provides no built-in signing mechanism; this control must be implemented at the pipeline level.

Sandbox model-loading environments. Where model files are loaded from untrusted or semi-trusted sources (e.g., a model marketplace, a partner integration), execute the load operation in an isolated environment (container or subprocess) with memory limits applied via cgroup constraints. This bounds the blast radius of the OOM DoS vector and limits the scope of the file-read offset vector.

Review for co-exposure with RAXE-2026-039. If CVE-2026-28500 (ONNX Hub silent warning bypass) has not yet been remediated, prioritise both together. The two vulnerabilities affect different code paths but the same package. Note that CVE-2026-28500 has no listed patched version in its GHSA (GHSA-hqmj-h5c6-369m); the fix was implemented by removing the affected feature. Upgrading to onnx >= 1.21.0 resolves CVE-2026-34445; organisations should verify independently that their version also addresses CVE-2026-28500.

Strategic

Treat ONNX model files as untrusted input. The security model implicit in many ML pipelines treats model files as inert data. This finding, in combination with RAXE-2026-039, demonstrates that ONNX models carry executable semantics — via structured metadata that is applied to runtime objects — that must be subject to the same scrutiny as code dependencies.


Intelligence Tradecraft

Analysis of Competing Hypotheses (ACH)

Hypothesis Evidence For Evidence Against Assessed Probability
H1: Vulnerability is exploitable for remote OOM DoS CVSS A:H; GHSA confirms length can be set arbitrarily via setattr(); PR:N, UI:N — no authentication or user interaction required No public PoC published as of 2026-04-03 High
H2: Dunder injection enables code execution GHSA notes __class__ injection is possible and "could lead to more complex exploits" No exploit chain demonstrated; CVSS does not reflect code execution; Python TypeError constrains assignment to compatible heap types Low — speculative; not confirmed
H3: Active exploitation in the wild Newly published 2026-04-01; EPSS 0.04% (12th percentile) No threat-intelligence reporting of active use as of 2026-04-03 Very low

Key Assumptions (KAC)

ID Assumption Confidence Impact if Wrong
KA-1 onnx 1.21.0 fully mitigates the setattr() issue — the fix commit replaces the unconstrained call with explicit validation High — fix commit cited in advisory, available in PyPI release If mitigation is incomplete, remediation guidance is insufficient
KA-2 The file-read offset manipulation (C:L/I:L) does not yield a practical arbitrary-read primitive beyond adjacent file data in typical deployments Medium — the GHSA description is brief on this vector's practical reach If wrong, the confidentiality impact should be re-evaluated upward
KA-3 Dunder attribute injection does not reach code execution without additional preconditions not described in public advisories Medium — no exploit chain published If a chain is published, CVSS and severity classification require revision
KA-4 Organisations loading only internally produced ONNX models with no external input are not materially at risk from this vulnerability High — the attack requires the adversary to supply a crafted model file If internal tooling generates adversarial metadata (e.g., via a compromised upstream dependency), scope broadens

Admiralty Grade: A2

Component Grade Rationale
Source Reliability A NVD is the official US government vulnerability database; GHSA is GitHub's reviewed advisory programme
Information Credibility 2 The vulnerability description is confirmed by fix commit e30c6935d67cc3eca2fa284e37248e7c0036c46b and merged PR #7751, both publicly verifiable

Full grade: A2 — reliable source, confirmed information.

Access Tier

T1 (black-box): the vulnerability is exploitable by any party that can supply a model file to the target, without access to the target's source code or internal systems.

Diamond Model

Facet Assessment
Adversary Unknown; no attributed actor. Reporter: ZeroXJacks (GitHub), credited in GHSA-538c-55jv-c5g9
Capability Craft a malicious .onnx model file with adversarial external_data metadata fields
Infrastructure Any model distribution channel: public hub, dependency mirror, partner API, direct file transfer
Victim ML pipelines that load ONNX models from external or partially-trusted sources

Timeline

Date Event
2026-04-01T18:16:30Z CVE-2026-34445 published to NVD
2026-04-01T21:10:52Z GHSA-538c-55jv-c5g9 published (GitHub Advisory Database)
2026-04-03 Signal ingested from NVD feed (TIB-2026-1015); finding promoted
2026-04-03 Brief, PoC, detection, and publication draft completed
2026-04-03 Publication date

References

# Type Title URL
1 CVE CVE-2026-34445: ONNX setattr() Attribute Injection — CVSS 8.6 HIGH (CNA-submitted) https://nvd.nist.gov/vuln/detail/CVE-2026-34445
2 Advisory GHSA-538c-55jv-c5g9: ONNX Malicious Model Object State Corruption and DoS via ExternalDataInfo https://github.com/advisories/GHSA-538c-55jv-c5g9
3 Tool Fix commit e30c6935: replace unconstrained setattr() in ExternalDataInfo https://github.com/onnx/onnx/commit/e30c6935d67cc3eca2fa284e37248e7c0036c46b
4 Tool PR #7751: object state corruption and DoS via ExternalDataInfo attribute injection https://github.com/onnx/onnx/pull/7751
5 Advisory PyPI onnx 1.21.0 — patched release, confirmed available https://pypi.org/project/onnx/1.21.0/
6 Other FIRST EPSS API: CVE-2026-34445 — Score 0.0004 (0.04%), Percentile 12th, 2026-04-03 https://api.first.org/data/v1/epss?cve=CVE-2026-34445
7 Other RAXE-2026-039: ONNX Hub Silent Security Warning Bypass (CVE-2026-28500) RAXE-2026-039

Appendix: RAXE Assessment Notes

Three-lane separation compliance. This draft observes the three-lane separation requirement. Statements of confirmed fact (CVE assignment, CVSS vector, fix commit, PyPI version availability) are presented as facts sourced to NVD or GHSA. Assessments by RAXE (probability of exploitation, practical reach of Vector 2, absence of a weaponised Vector 3 chain) are labelled "RAXE assessment". Claims sourced to GHSA advisory text are quoted directly or attributed to GHSA-538c-55jv-c5g9 by reference.

CVSS score sourcing. The CVSS score of 8.6 HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H) is the CNA-submitted score as recorded in the NVD entry for CVE-2026-34445. NVD's own analysis is not yet complete (status: "Undergoing Analysis" as of 2026-04-03). The fact-check report confirms the metadata CVSS matches the NVD-recorded value (delta 0.0). This advisory will be updated if the score changes materially once analysis is complete.

Severity label. CVSS 8.6 maps to HIGH severity (7.0–8.9 range per NVD severity scale). This finding is assessed as high-severity. The word "critical" does not appear in this advisory in reference to the severity of this finding.

Dunder vector uncertainty. The advisory states that dunder attribute injection "could lead to more complex exploits" (GHSA-538c-55jv-c5g9). RAXE has not independently verified a complete exploit chain via this vector. The assessment in this advisory treats Vector 3 as a potential precondition for further exploitation rather than a demonstrated exploit path, consistent with the available public evidence.

ATLAS mapping. No MITRE ATLAS technique ID has been verified for this specific attack vector as of 2026-04-03. The pattern aligns broadly with ML supply-chain threat categories. A formal ATLAS mapping is deferred until a verified technique ID can be confirmed against the ATLAS v5.4.0 lookup table.