Instructions to use Hironabe333/keras-duplicate-weights-h5-poc with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use Hironabe333/keras-duplicate-weights-h5-poc with Keras:
# Available backend options are: "jax", "torch", "tensorflow". import os os.environ["KERAS_BACKEND"] = "jax" import keras model = keras.saving.load_model("hf://Hironabe333/keras-duplicate-weights-h5-poc") - Notebooks
- Google Colab
- Kaggle
YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
Keras .keras duplicate model.weights.h5 β PoC
Summary
A .keras file is a ZIP archive. When it contains two entries both named
model.weights.h5, Python's zipfile.ZipFile.read() resolves to the last
entry. keras.saving.load_model() therefore loads trained weights from the later
entry. safe_mode=True does not prevent this. ModelScan 0.8.8 reports 0 issues.
Technical distinction
This issue affects the weight archive member, model.weights.h5, rather than
model architecture metadata. The crafted archive contains a single unchanged
config.json; only the weight file member is duplicated. The model architecture
remains the same, but the trained parameters selected by the loader change.
| Architecture/config duplicate | This report | |
|---|---|---|
| Duplicate member | config.json |
model.weights.h5 |
| Attack target | model architecture / config | trained weights (parameters) |
| Manipulation | architecture/config behavior | direct parameter replacement |
config.json in this PoC |
(not applicable) | single and unchanged |
| Required mitigation | reject duplicate config metadata | reject duplicate weight archive members |
Requirements
- Python 3.9+
KERAS_BACKEND=torch(no TensorFlow required)
pip install -r requirements.txt
Reproduce
KERAS_BACKEND=torch python make_duplicate_weights_h5.py
KERAS_BACKEND=torch python check_duplicate_weights_h5.py
The scripts confirm that Keras loads the second model.weights.h5 entry
and produces different outputs from the baseline model.
Artifacts
| File | Description |
|---|---|
benign_weights_single.keras |
Baseline model (single model.weights.h5, benign weights) |
dup_model_weights_h5.keras |
Crafted file: first entry benign, second entry malicious weights |
make_duplicate_weights_h5.py |
Generates both files |
check_duplicate_weights_h5.py |
Verifies loader behavior and inference differential |
Impact
A reviewer or tool that inspects only one model.weights.h5 archive member
would see benign trained weights:
kernel = [[1.0], [1.0]] bias = [0.0] β output = x0 + x1
Loading the file with keras.saving.load_model() β including safe_mode=True
β produces different output, because Keras resolves to the last duplicate entry:
kernel = [[-1.0], [-1.0]] bias = [5.0] β output = -(x0+x1) + 5
Observed inference differential:
| Input | Benign output | Crafted model output |
|---|---|---|
| [1.0, 0.0] | 1.0 | 4.0 |
| [0.0, 1.0] | 1.0 | 4.0 |
| [1.0, 1.0] | 2.0 | 3.0 |
- Downloads last month
- 18