{"slug": "statically-catching-the-cve-2026-34445-onnx-external-data-attribute-injection", "title": "Statically catching the CVE-2026-34445 ONNX external_data attribute-injection vector before the model loads", "summary": "A developer at Munim, Inc. released a free, Apache-2.0 static scanner that detects the CVE-2026-34445 attribute-injection vector in ONNX models before any loader runs. The tool, shipped as v0.13.0 of keras-model-scan, flags unexpected keys in a tensor's external_data field, which in onnx versions before 1.21.0 were passed to setattr without validation and could overwrite a loader's internal state and crash a model-serving process at load time. The scanner uses only the Python standard library and never executes or loads the model, exiting non-zero when a finding at or above a configurable severity threshold is present so it can serve as a CI gate.", "body_md": "*Made with AI: the scanner and this post were made with AI agents working for me, MV2 of Munim, Inc.*\n\nAn `.onnx` file looks like a safe thing to download. It is a protobuf message with no code of its own: no pickle, no Lambda layer, nothing that runs. But a parser still has to read it, and in `onnx` before 1.21.0 one small field let a crafted file reach into the loader's own Python objects. This post explains that field, the advisory, and a free static check that flags it before any loader runs.\n\n`external_data`\nBig models keep their weights outside the `.onnx` file. A tensor whose `data_location` is `EXTERNAL` names its weights file through a list of key/value string pairs in the tensor's `external_data` field. The ONNX spec recognises only four keys:\n\n| key | meaning | \n|---|---|\n| `location` | path of the data file (required) | \n| `offset` | byte offset where the tensor's data begins | \n| `length` | number of bytes | \n| `checksum` | SHA1 digest of the data file | \n\n`onnx` >= 1.21.0 also keeps `basepath`, for save/load round-trips.\n\nBefore 1.21.0, `onnx`'s `ExternalDataInfo` read those pairs by calling `setattr(self, key, value)` for **every** key, without validating it. So a crafted model carrying an unexpected key (a Python dunder such as `__class__`, or any other attribute name) could overwrite the object's internal state and crash a model-serving process at load time.\n\n`onnx` < 1.21.0`onnx_external_data_key_scan.py`\nI shipped a free, Apache-2.0 scanner for exactly this vector, released as v0.13.0 of keras-model-scan. It uses only the Python standard library and never executes or loads the model:\n\n`{location, offset, length, checksum, basepath}` as In CI, one line:\n\n```\npython onnx_external_data_key_scan.py ./model-dir --fail-on HIGH\n```\n\nThe exit code is non-zero when a finding at or above `--fail-on` is present, so it works as a gate.\n\nWhy a separate tool? Existing model scanners such as ModelScan and ModelAudit check ONNX custom ops and `external_data` path traversal (`location` pointing outside the model directory), but as far as I can tell not unexpected `external_data` keys. So this appears to be the first standalone detector for this exact vector. If I have missed one, please tell me and I will correct this.\n\nScanner and full write-up: [https://github.com/munimtechnologies/keras-model-scan/blob/main/ONNX_EXTERNAL_DATA_KEY_SCAN.md](https://github.com/munimtechnologies/keras-model-scan/blob/main/ONNX_EXTERNAL_DATA_KEY_SCAN.md) (repo: [https://github.com/munimtechnologies/keras-model-scan](https://github.com/munimtechnologies/keras-model-scan)). Issues and corrections are welcome.\n\n*MV2 of Munim, Inc.*", "url": "https://wpnews.pro/news/statically-catching-the-cve-2026-34445-onnx-external-data-attribute-injection", "canonical_source": "https://dev.to/munimv2/statically-catching-the-cve-2026-34445-onnx-externaldata-attribute-injection-vector-before-the-1bl6", "published_at": "2026-10-15 18:17:34+00:00", "updated_at": "2026-10-15 18:24:24.234207+00:00", "lang": "en", "topics": ["ai-safety", "ai-infrastructure", "mlops", "developer-tools", "artificial-intelligence"], "entities": ["Munim, Inc.", "ONNX", "keras-model-scan", "CVE-2026-34445", "ModelScan", "ModelAudit"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/statically-catching-the-cve-2026-34445-onnx-external-data-attribute-injection", "markdown": "https://wpnews.pro/news/statically-catching-the-cve-2026-34445-onnx-external-data-attribute-injection.md", "text": "https://wpnews.pro/news/statically-catching-the-cve-2026-34445-onnx-external-data-attribute-injection.txt", "jsonld": "https://wpnews.pro/news/statically-catching-the-cve-2026-34445-onnx-external-data-attribute-injection.jsonld"}}