Instructions to use celvexgroup/modelscan-keras-loss-lambda-bypass-poc with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use celvexgroup/modelscan-keras-loss-lambda-bypass-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://celvexgroup/modelscan-keras-loss-lambda-bypass-poc") - Notebooks
- Google Colab
- Kaggle
| 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. | |