unicuervo's picture
Upload 5 files
1e04c70 verified
|
Raw
History Blame Contribute Delete
2.57 kB
---
license: apache-2.0
tags:
- keras
- modelscan
- model-file-vulnerability
- security
---
# Keras Native nested Lambda ModelScan bypass PoC
This repository contains a benign proof-of-concept `.keras` model for a Huntr Model File Vulnerability report.
## Summary
The file `nested_lambda.keras` contains a Keras `Lambda` layer nested inside an inner `Functional` model.
ModelScan detects a top-level Keras `Lambda` layer, but this nested variant is reported as clean:
```text
--- Summary ---
No issues found!
```
However, recursive inspection of `config.json` shows the hidden Lambda:
```text
[TOP_LEVEL_LAMBDAS] []
[RECURSIVE_LAMBDA_COUNT] 1
[RECURSIVE_LAMBDA] hidden_lambda at $.config.layers[1].config.layers[1]
```
Keras itself recognizes the nested Lambda as unsafe during default loading and blocks it with `safe_mode=True`.
When the same model is loaded with `safe_mode=False`, the nested Lambda is deserialized and changes model behavior. This PoC only performs benign output manipulation and returns `1337.0` for input `5.0`.
## Files
- `nested_lambda.keras`: benign PoC model file.
- `reproduce.py`: local reproduction script.
- `requirements.txt`: dependency list.
- `generate_model.py`: optional script to regenerate the PoC model.
## Reproduction
Install dependencies:
```bash
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
```
Run ModelScan:
```bash
modelscan -p nested_lambda.keras
```
Expected result:
```text
No issues found!
```
Run the local reproduction:
```bash
KERAS_BACKEND=tensorflow python reproduce.py
```
Expected result:
```text
[TOP_LEVEL_LAMBDAS] []
[RECURSIVE_LAMBDA_COUNT] 1
[RECURSIVE_LAMBDA] hidden_lambda at $.config.layers[1].config.layers[1]
[DEFAULT_LOAD_BLOCKED] ValueError
Requested the deserialization of a `Lambda` layer whose `function` is a Python lambda.
[UNSAFE_LOAD_OK]
[OUTPUT] [[1337.0]]
```
## Security impact
A scanner or model registry relying on ModelScan may incorrectly classify a `.keras` model as clean even though it contains an unsafe Lambda layer.
This is a scanner bypass / false negative. The PoC does not claim code execution under Keras default `safe_mode=True`. Keras blocks the nested Lambda by default. The impact is that ModelScan fails to detect the same unsafe construct that Keras later identifies and blocks.
If a downstream consumer trusts the clean ModelScan result and loads the model with `safe_mode=False` or globally enables unsafe deserialization, the hidden Lambda is deserialized and can manipulate model behavior.