Instructions to use captainarp/h5-torch-wrapper-modelscan-bypass-poc with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use captainarp/h5-torch-wrapper-modelscan-bypass-poc with Keras:
# !pip install -U keras tensorflow huggingface_hub # Keras needs TensorFlow installed to read "hf://" paths, so the tensorflow backend is selected here; # "jax" and "torch" also work for computation once TensorFlow is installed. import os os.environ["KERAS_BACKEND"] = "tensorflow" import keras model = keras.saving.load_model("hf://captainarp/h5-torch-wrapper-modelscan-bypass-poc") - Notebooks
- Google Colab
- Kaggle
Download huntr_report_draft.md from captainarp/h5-torch-wrapper-modelscan-bypass-poc: direct link, hf CLI and curl.
- Browser
- Download file 3.5 kB
-
https://huggingface.co/captainarp/h5-torch-wrapper-modelscan-bypass-poc/resolve/main/huntr_report_draft.md
- Command line
-
hf download hf://captainarp/h5-torch-wrapper-modelscan-bypass-poc/huntr_report_draft.md
-
curl -L -o huntr_report_draft.md https://huggingface.co/captainarp/h5-torch-wrapper-modelscan-bypass-poc/resolve/main/huntr_report_draft.md
Summary
This report demonstrates a ModelScan scanner bypass for an HDF5/Keras-H5 model file containing an unsafe TorchModuleWrapper deserialization path.
ModelScan 0.8.8 scans the submitted .h5 file with H5LambdaDetectScan and reports 0 issues and 0 errors. The same H5 model_config contains a keras.layers.TorchModuleWrapper layer with a base64-encoded pickle payload in the module field.
Keras itself treats this path as unsafe: default safe_mode=True blocks it. When unsafe deserialization is explicitly enabled with safe_mode=False, Keras reaches torch.load(..., weights_only=False) and the embedded payload writes a harmless marker file.
Affected Format
HDF5 / Keras H5 .h5
Security Impact
This is a scanner bypass for an unsafe HDF5/Keras-H5 deserialization construct.
If a downstream workflow relies on ModelScan to decide whether a .h5 model file is safe, this payload is reported clean. If the same model is later loaded in a workflow that enables unsafe Keras deserialization, the embedded torch.load() pickle path executes code during model loading.
The PoC payload is intentionally non-destructive. It only writes:
h5_torch_wrapper_marker.txt
with contents:
H5_TORCH_WRAPPER_BYPASS
Reproduction Steps
Download or clone the public Hugging Face PoC repo.
Install dependencies:
pip install -r requirements.txt
- Run the verifier:
python verify_poc.py --payload poc_h5_torch_wrapper.h5
- Observe that ModelScan reports:
0 issues
0 errors
total_scanned: 1
- Observe that default Keras loading blocks the unsafe path:
Marker after safe_mode=True: False
- Observe that unsafe deserialization reaches the embedded
torch.load()path and writes the marker:
Marker after safe_mode=False: True
Marker contents: H5_TORCH_WRAPPER_BYPASS
Root Cause
ModelScan's H5 scanner checks the H5 model_config for layers whose class_name is Lambda, but it does not detect other unsafe Keras deserialization constructs such as keras.layers.TorchModuleWrapper.
Keras treats TorchModuleWrapper as unsafe because TorchModuleWrapper.from_config() can base64-decode the module field and pass it to:
torch.load(..., weights_only=False)
This can execute attacker-controlled pickle payloads when unsafe deserialization is enabled.
Scope Note
This is not a claim that default Keras loading executes the payload. Default safe_mode=True blocks the unsafe TorchModuleWrapper deserialization path.
The reported issue is that ModelScan reports 0 issues and 0 errors for an HDF5/Keras-H5 file containing an unsafe construct that Keras itself treats as dangerous. ModelScan already flags Lambda layers in H5 model_config, but it does not flag TorchModuleWrapper.
Evidence
PoC file:
poc_h5_torch_wrapper.h5
Verification script:
verify_poc.py
Scanner output:
modelscan_result_h5_torch_wrapper.json
Tested versions:
modelscan==0.8.8
h5py==3.16.0
keras==3.15.0
tensorflow==2.17.1
torch==2.12.1+cpu
Suggested Remediation
ModelScan should extend H5 model_config scanning beyond Lambda layers and flag unsafe Keras deserialization constructs that Keras itself protects with safe mode, including keras.layers.TorchModuleWrapper.
For TorchModuleWrapper, ModelScan should inspect the module field, recognize it as a base64-encoded pickle / torch serialization payload, and either flag it directly or pass it through the existing unsafe pickle scanner.