celvexgroup's picture
Upload 3 files
29c9690 verified
|
Raw
History Blame Contribute Delete
1.9 kB
---
license: apache-2.0
tags:
- security
- coordinated-disclosure
- modelscan
---
# Benign PoC β€” modelscan Keras positional Lambda-scan bypass (compiled loss)
Coordinated-disclosure proof-of-concept for Protect AI `modelscan`, submitted via huntr (Model File Vulnerability).
modelscan's Keras/H5 Lambda detection (`KerasLambdaDetectScan` / `H5LambdaDetectScan`) is **positional**:
it flags only a top-level layer with `class_name=="Lambda"`. A marshalled-bytecode lambda serialized as
the model's compiled **loss** (in `compile_config`, which the DEFAULT `load_model(compile=True)`
deserializes) is never inspected β€” so a model that executes attacker bytecode on load+evaluate scans **clean**.
- `evil_loss.keras` β€” lambda in `compile_config.loss` β†’ modelscan: **No issues found** (the bypass)
- `control_lambda.keras` β€” the **identical** benign function as a Lambda **layer** β†’ modelscan: **MEDIUM `Lambda`** (control)
## Reproduce
```
pip install tensorflow modelscan
modelscan -p evil_loss.keras # -> No issues found (bypass)
modelscan -p control_lambda.keras # -> MEDIUM 'Lambda' from Keras (same function, caught as a layer)
python - <<'PY'
import keras, numpy as np
keras.config.enable_unsafe_deserialization()
m = keras.models.load_model("evil_loss.keras", safe_mode=False, compile=True)
m.evaluate(np.zeros((2,4)), np.zeros((2,1))) # -> writes /tmp/celvex_mfv_keras_marker.txt
PY
```
The lambda reconstructs from marshalled bytecode and runs when the loss is invoked (evaluate/fit) after a
default `load_model(compile=True, safe_mode=False)` β€” the same safe-mode premise as the accepted
Lambda-layer class, but from a config position modelscan does not scan.
**Strictly benign:** the lambda only writes a marker string (`CELVEX-MFV-KERAS-LOSS-MARKER`). No
weaponization. Validated against modelscan 0.8.8 + tensorflow/keras 3.15.0.