VYPR
High severityNVD Advisory· Published Jun 6, 2024· Updated Aug 1, 2024

Arbitrary File Overwrite in download_model_with_test_data in onnx/onnx

CVE-2024-5187

Description

A vulnerability in the download_model_with_test_data function of the onnx/onnx framework, version 1.16.0, allows for arbitrary file overwrite due to inadequate prevention of path traversal attacks in malicious tar files. This vulnerability enables attackers to overwrite any file on the system, potentially leading to remote code execution, deletion of system, personal, or application files, thus impacting the integrity and availability of the system. The issue arises from the function's handling of tar file extraction without performing security checks on the paths within the tar file, as demonstrated by the ability to overwrite the /home/kali/.ssh/authorized_keys file by specifying an absolute path in the malicious tar file.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2024-5187 allows arbitrary file overwrite via path traversal in ONNX's download_model_with_test_data function.

Vulnerability

Description

The vulnerability resides in the download_model_with_test_data function of the ONNX framework, version 1.16.0. The function extracts tar files without validating the paths of contained files, making it susceptible to path traversal attacks. An attacker can craft a malicious tar file containing entries with absolute paths (e.g., /home/kali/.ssh/authorized_keys) that, when extracted, overwrite arbitrary files on the system. This lack of security checks on the tar contents enables the vulnerability [2].

Attack

Vector and Exploitation

Exploitation requires an attacker to provide a malicious tar file to the vulnerable function. The function processes the tar file without sanitizing the paths, allowing an entry with an absolute path to be written directly to the filesystem. This attack does not require authentication if the function is exposed to untrusted input, such as when downloading models from third-party repositories [1]. The pull request that introduced the fix highlights the need to mitigate tarball extraction risks [1].

Impact

Successful exploitation grants an attacker the ability to overwrite any file on the system. This could lead to remote code execution (e.g., overwriting SSH authorized_keys), denial of service by deleting critical system files, or compromising the integrity of application data. The vulnerability impacts the Confidentiality, Integrity, and Availability of the system, with the potential for complete system compromise [2].

Mitigation

The vulnerability has been addressed in pull requests #6145 and #6222, which introduced a safe extraction method that validates paths and prevents path traversal [1][3]. Users are strongly advised to update to a patched version of the ONNX framework. No workarounds have been officially provided, and the issue should be resolved by applying the available patches.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
onnxPyPI
< 1.16.21.16.2

Affected products

2
  • ghsa-coords
    Range: < 1.16.2
  • onnx/onnx/onnxv5
    Range: unspecified

Patches

2
1b70f9b67325

Refactor safe extract method to fix issue 6215 (#6222)

https://github.com/onnx/onnxliqun FuJul 16, 2024via ghsa
3 files changed · +72 50
  • onnx/backend/test/runner/__init__.py+1 3 modified
    @@ -10,7 +10,6 @@
     import re
     import shutil
     import sys
    -import tarfile
     import tempfile
     import time
     import unittest
    @@ -242,8 +241,7 @@ def download_model(
                 )
                 urlretrieve(model_test.url, download_file.name)
                 print("Done")
    -            with tarfile.open(download_file.name) as t:
    -                t.extractall(models_dir)
    +            onnx.utils._extract_model_safe(download_file.name, models_dir)
             except Exception as e:
                 print(f"Failed to prepare data for model {model_test.model_name}: {e}")
                 raise
    
  • onnx/hub.py+8 47 modified
    @@ -11,7 +11,6 @@
     import json
     import os
     import sys
    -import tarfile
     from io import BytesIO
     from os.path import join
     from typing import IO, Any, Dict, List, cast
    @@ -290,35 +289,6 @@ def load(
         return onnx.load(cast(IO[bytes], BytesIO(model_bytes)))
     
     
    -def _tar_members_filter(tar: tarfile.TarFile, base: str) -> list[tarfile.TarInfo]:
    -    """Check that the content of ``tar`` will be extracted safely
    -
    -    Args:
    -        tar: The tarball file
    -        base: The directory where the tarball will be extracted
    -
    -    Returns:
    -        list of tarball members
    -    """
    -    result = []
    -    for member in tar:
    -        member_path = os.path.join(base, member.name)
    -        abs_base = os.path.abspath(base)
    -        abs_member = os.path.abspath(member_path)
    -        if not abs_member.startswith(abs_base):
    -            raise RuntimeError(
    -                f"The tarball member {member_path} in downloading model contains "
    -                f"directory traversal sequence which may contain harmful payload."
    -            )
    -        elif member.issym() or member.islnk():
    -            raise RuntimeError(
    -                f"The tarball member {member_path} in downloading model contains "
    -                f"symbolic links which may contain harmful payload."
    -            )
    -        result.append(member)
    -    return result
    -
    -
     def download_model_with_test_data(
         model: str,
         repo: str = "onnx/models:main",
    @@ -393,23 +363,14 @@ def download_model_with_test_data(
                     "download the model from the model hub."
                 )
     
    -    with tarfile.open(local_model_with_data_path) as model_with_data_zipped:
    -        # FIXME: Avoid index manipulation with magic numbers
    -        local_model_with_data_dir_path = local_model_with_data_path[
    -            0 : len(local_model_with_data_path) - 7
    -        ]
    -        # Mitigate tarball directory traversal risks
    -        if hasattr(tarfile, "data_filter"):
    -            model_with_data_zipped.extractall(
    -                path=local_model_with_data_dir_path, filter="data"
    -            )
    -        else:
    -            model_with_data_zipped.extractall(
    -                path=local_model_with_data_dir_path,
    -                members=_tar_members_filter(
    -                    model_with_data_zipped, local_model_with_data_dir_path
    -                ),
    -            )
    +    # FIXME: Avoid index manipulation with magic numbers,
    +    # remove ".tar.gz"
    +    local_model_with_data_dir_path = local_model_with_data_path[
    +        0 : len(local_model_with_data_path) - 7
    +    ]
    +    onnx.utils._extract_model_safe(
    +        local_model_with_data_path, local_model_with_data_dir_path
    +    )
         model_with_data_path = (
             local_model_with_data_dir_path
             + "/"
    
  • onnx/utils.py+63 0 modified
    @@ -4,6 +4,7 @@
     from __future__ import annotations
     
     import os
    +import tarfile
     
     import onnx.checker
     import onnx.helper
    @@ -232,3 +233,65 @@ def extract_model(
         onnx.save(extracted, output_path)
         if check_model:
             onnx.checker.check_model(output_path)
    +
    +
    +def _tar_members_filter(
    +    tar: tarfile.TarFile, base: str | os.PathLike
    +) -> list[tarfile.TarInfo]:
    +    """Check that the content of ``tar`` will be extracted safely
    +
    +    Args:
    +        tar: The tarball file
    +        base: The directory where the tarball will be extracted
    +
    +    Returns:
    +        list of tarball members
    +    """
    +    result = []
    +    for member in tar:
    +        member_path = os.path.join(base, member.name)
    +        abs_base = os.path.abspath(base)
    +        abs_member = os.path.abspath(member_path)
    +        if not abs_member.startswith(abs_base):
    +            raise RuntimeError(
    +                f"The tarball member {member_path} in downloading model contains "
    +                f"directory traversal sequence which may contain harmful payload."
    +            )
    +        elif member.issym() or member.islnk():
    +            raise RuntimeError(
    +                f"The tarball member {member_path} in downloading model contains "
    +                f"symbolic links which may contain harmful payload."
    +            )
    +        result.append(member)
    +    return result
    +
    +
    +def _extract_model_safe(
    +    model_tar_path: str | os.PathLike, local_model_with_data_dir_path: str | os.PathLike
    +) -> None:
    +    """Safely extracts a tar file to a specified directory.
    +
    +    This function ensures that the extraction process mitigates against
    +    directory traversal vulnerabilities by validating or sanitizing paths
    +    within the tar file. It also provides compatibility for different versions
    +    of the tarfile module by checking for the availability of certain attributes
    +    or methods before invoking them.
    +
    +    Args:
    +        model_tar_path: The path to the tar file to be extracted.
    +        local_model_with_data_dir_path: The directory path where the tar file
    +      contents will be extracted to.
    +    """
    +    with tarfile.open(model_tar_path) as model_with_data_zipped:
    +        # Mitigate tarball directory traversal risks
    +        if hasattr(tarfile, "data_filter"):
    +            model_with_data_zipped.extractall(
    +                path=local_model_with_data_dir_path, filter="data"
    +            )
    +        else:
    +            model_with_data_zipped.extractall(
    +                path=local_model_with_data_dir_path,
    +                members=_tar_members_filter(
    +                    model_with_data_zipped, local_model_with_data_dir_path
    +                ),
    +            )
    
3fc3845edb04

Mitigate tarball directory traversal risks (#6164)

https://github.com/onnx/onnxsunflowersxuJun 12, 2024via ghsa
1 file changed · +42 1
  • onnx/hub.py+42 1 modified
    @@ -290,6 +290,35 @@ def load(
         return onnx.load(cast(IO[bytes], BytesIO(model_bytes)))
     
     
    +def _tar_members_filter(tar: tarfile.TarFile, base: str) -> list[tarfile.TarInfo]:
    +    """Check that the content of ``tar`` will be extracted safely
    +
    +    Args:
    +        tar: The tarball file
    +        base: The directory where the tarball will be extracted
    +
    +    Returns:
    +        list of tarball members
    +    """
    +    result = []
    +    for member in tar:
    +        member_path = os.path.join(base, member.name)
    +        abs_base = os.path.abspath(base)
    +        abs_member = os.path.abspath(member_path)
    +        if not abs_member.startswith(abs_base):
    +            raise RuntimeError(
    +                f"The tarball member {member_path} in downloading model contains "
    +                f"directory traversal sequence which may contain harmful payload."
    +            )
    +        elif member.issym() or member.islnk():
    +            raise RuntimeError(
    +                f"The tarball member {member_path} in downloading model contains "
    +                f"symbolic links which may contain harmful payload."
    +            )
    +        result.append(member)
    +    return result
    +
    +
     def download_model_with_test_data(
         model: str,
         repo: str = "onnx/models:main",
    @@ -298,6 +327,7 @@ def download_model_with_test_data(
         silent: bool = False,
     ) -> str | None:
         """Downloads a model along with test data by name from the onnx model hub and returns the directory to which the files have been extracted.
    +    Users are responsible for making sure the model comes from a trusted source, and the data is safe to be extracted.
     
         Args:
             model: The name of the onnx model in the manifest. This field is
    @@ -368,7 +398,18 @@ def download_model_with_test_data(
             local_model_with_data_dir_path = local_model_with_data_path[
                 0 : len(local_model_with_data_path) - 7
             ]
    -        model_with_data_zipped.extractall(local_model_with_data_dir_path)
    +        # Mitigate tarball directory traversal risks
    +        if hasattr(tarfile, "data_filter"):
    +            model_with_data_zipped.extractall(
    +                path=local_model_with_data_dir_path, filter="data"
    +            )
    +        else:
    +            model_with_data_zipped.extractall(
    +                path=local_model_with_data_dir_path,
    +                members=_tar_members_filter(
    +                    model_with_data_zipped, local_model_with_data_dir_path
    +                ),
    +            )
         model_with_data_path = (
             local_model_with_data_dir_path
             + "/"
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.