treforbenbow's picture
Upload README.md with huggingface_hub
c8f1008 verified
# VULN-016: Arbitrary File Read via ONNX External Data Path Traversal in TensorRT
## Vulnerability
TensorRT's ONNX parser (`libnvonnxparser`) allows absolute file paths in the `external_data.location` field of ONNX TensorProto initializers. When a victim loads a malicious ONNX model, arbitrary files from their filesystem are read as model weights and embedded into the compiled TensorRT engine.
**CWE-22**: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
## Severity
**Critical (CVSS 3.1: 9.1)**
## Root Cause
`normalizePath()` in `weightUtils.cpp` blocks `../` relative directory traversal but does NOT reject absolute paths like `C:/Windows/win.ini` or `/etc/passwd`. The absolute path passes through all validation and is used directly in `CreateFileMapping()` / `mmap()`.
## Affected Versions
- TensorRT 10.16.0.29 (tested)
- Likely all TensorRT versions with ONNX external data support
## Impact
An attacker can craft a ~200-byte ONNX model that, when loaded by TensorRT:
1. Reads arbitrary files from the victim's filesystem
2. Embeds file contents into the compiled TensorRT engine
3. Exposes stolen data through inference output
Attack scenarios: steal SSH keys, cloud credentials, application configs, proprietary models.
## Files
| File | Description |
|------|-------------|
| `poc_windows.onnx` | PoC model targeting `C:/Windows/win.ini` (Windows) |
| `poc_linux.onnx` | PoC model targeting `/etc/hostname` (Linux) |
| `reproduce.py` | Reproduction script ? loads PoC model and extracts stolen file contents |
| `create_malicious_model.py` | Tool to create custom malicious models targeting any file |
## Reproduction
```bash
# 1. Install requirements
pip install tensorrt numpy onnx
# 2. Run the PoC (Windows)
python reproduce.py poc_windows.onnx
# 3. Or create a custom exploit model
python create_malicious_model.py C:/Users/victim/.ssh/id_rsa exploit.onnx 4096
python reproduce.py exploit.onnx
```
## Expected Output
```
[*] Loading model: poc_windows.onnx
[+] Parse succeeded - external file was read as model weights!
[+] Engine built - file contents now embedded in TensorRT engine
[+] Extracted 92 bytes from target file:
----------------------------------------
; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1
----------------------------------------
```
## Verified Reads
| Target File | Result |
|---|---|
| `C:/Windows/System32/kernel32.dll` | Read successful (4096 bytes) |
| `C:/Windows/System32/ntdll.dll` | Read successful (4096 bytes) |
| `C:/Windows/win.ini` | Read successful ? byte-for-byte content match verified |
## Suggested Fix
In `parseExternalWeights()`, reject absolute paths:
```cpp
std::string normalizedFile = normalizePath(file);
if (normalizedFile.find("../") != std::string::npos) return false;
// ADD: reject absolute paths
if (!normalizedFile.empty() && (normalizedFile[0] == '/' || normalizedFile[0] == '\\'))
return false;
if (normalizedFile.size() > 1 && normalizedFile[1] == ':')
return false;
```
## Related CVEs
- CVE-2022-25882: ONNX library path traversal via external_data
- CVE-2024-27318: Bypass of CVE-2022-25882 fix
- CVE-2024-5187: ONNX path traversal via tar
- CVE-2025-51480: ONNX save_external_data path traversal
TensorRT's C++ parser has its own independent implementation that does not inherit fixes from the ONNX Python library.