You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

PoC β€” ModelScan does not scan .hdf5 files and reports them as clean

Security research artefact for a huntr Model File Vulnerability report. Not a usable model. Do not load these files outside a disposable sandbox.

What is in this repo

Two byte-identical copies of one Keras model:

file sha256
sentiment_model.h5 4b936709f91d4c46a9dbf6cd73bcdbeb10e46aed9f24add1acf4da7d401efb80
sentiment_model.hdf5 4b936709f91d4c46a9dbf6cd73bcdbeb10e46aed9f24add1acf4da7d401efb80

The only difference is the filename extension.

The model is an ordinary 4-layer Sequential (Dense β†’ Lambda β†’ Dense). The Lambda layer carries a marshalled anonymous lambda. The payload is inert: it creates /tmp/huntr_exec/PWNED and returns its input unchanged. It is a stand-in for arbitrary code β€” nothing here is destructive.

The issue

ModelScan classifies a file purely by exact filename suffix (modelscan/middlewares/format_via_extension.py):

extension = model.get_source().suffix
formats = [
    format
    for format, extensions in self._settings["formats"].items()
    if extension in extensions
]

settings.py maps KERAS_H5: [".h5"]. It does not map .hdf5.

When nothing matches, the file gets no format context, every scanner returns early on its if FORMAT not in model.get_context("formats") guard, and the file is never inspected β€” yet the run still prints No issues found! πŸŽ‰. The skip is visible only behind the non-default --show-skipped flag.

Meanwhile keras.saving.load_model accepts both extensions identically (keras/src/saving/saving_api.py:83,196):

if str(filepath).endswith((".h5", ".hdf5")):

So the two files are the same model to the loader, and different files to the scanner.

Reproduction

pip install "modelscan[tensorflow]"

modelscan -p sentiment_model.h5
#   Total Issues: 1
#   - Severity: MEDIUM
#   - Description: Use of unsafe operator 'Lambda' from module 'Keras'

modelscan -p sentiment_model.hdf5 --show-skipped
#    No issues found! πŸŽ‰
#   Skipped files list:
#   The following file sentiment_model.hdf5 was skipped during a ModelScan scan:
#   Model Scan did not scan file

Confirming both files are the same model to Keras (run in a sandbox):

import keras
keras.saving.load_model("sentiment_model.hdf5", safe_mode=False, compile=False)
# -> loads; /tmp/huntr_exec/PWNED now exists

Measured results

modelscan (latest, tensorflow extras) / keras 3.15.0:

file ModelScan verdict load_model(safe_mode=True) load_model(safe_mode=False)
sentiment_model.h5 Total Issues: 1 (MEDIUM) blocked executes
sentiment_model.hdf5 No issues found β€” not scanned blocked executes

Scope note

Keras 3.15.0 correctly enforces safe_mode=True for both files, so this is not a Keras vulnerability and no Keras RCE is claimed. The defect is in ModelScan: it is the control used to decide whether a model file is safe before it is loaded, and it returns "clean" for a file it never opened. Anyone loading with safe_mode=False β€” required for any legitimate Lambda-bearing model, and the usual workaround when a load fails β€” gets code execution on a file the gate passed.

.hdf5 is a standard, documented HDF5 extension, and ModelScan's README states it supports "H5".

Suggested fix

Classify by content, not by suffix β€” HDF5 files begin with the magic bytes \x89HDF\r\n\x1a\n. And when a file cannot be classified, surface it as an explicit unscanned result in the default summary instead of folding it into "No issues found".

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support