Keras TorchModuleWrapper ModelScan Bypass PoC

This is a harmless proof-of-concept for a .keras ModelScan scanner gap.

The .keras file embeds a keras.layers.TorchModuleWrapper config containing a base64-encoded pickle payload in the module field. Keras treats this path as unsafe and blocks it under default safe_mode=True, because TorchModuleWrapper.from_config() calls torch.load() when unsafe deserialization is enabled.

ModelScan 0.8.8 with TensorFlow extras scans the .keras file and reports 0 issues and 0 errors, because its .keras scanner only detects Lambda layers in config.json.

The payload is non-destructive. It only writes keras_torch_wrapper_marker.txt containing KERAS_TORCH_WRAPPER_BYPASS when loaded with safe_mode=False.

Files

  • poc_keras_torch_wrapper.keras - .keras PoC archive.
  • generate_torch_wrapper_keras_poc.py - regenerates the PoC archive.
  • verify_poc.py - runs ModelScan, then tests Keras default safe mode and unsafe deserialization.
  • modelscan_result_keras_torch_wrapper_tf.json - captured clean ModelScan result using modelscan==0.8.8 with TensorFlow installed.
  • requirements.txt - tested dependency versions.
  • huntr_report_draft.md - draft report text.

Reproduce

pip install -r requirements.txt
python verify_poc.py --payload poc_keras_torch_wrapper.keras

Expected result:

ModelScan issues: 0
ModelScan errors: 0
Marker after safe_mode=True: False
Marker after safe_mode=False: True
Marker contents: KERAS_TORCH_WRAPPER_BYPASS

Scope Note

This is not a claim that default Keras loading executes the payload. Default safe_mode=True blocks the unsafe TorchModuleWrapper deserialization path. The report is that ModelScan misses an unsafe .keras construct that Keras itself treats as dangerous, while ModelScan already flags Lambda layers despite their own safe-mode protections.

Downloads last month
2
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support