Disallow TFSMLayer deserialization in safe_mode to prevent external SavedModel execution by 0xManan · Pull Request #22035 · keras-team/keras (original) (raw)
and others added 5 commits
Added safe mode checks for loading TFSMLayer from external SavedModels.
…avedModel execution
TFSMLayer currently loads external TensorFlow SavedModels during deserialization
without respecting Keras safe_mode. Although TensorFlow does not execute
SavedModel functions at load time, the attacker-controlled graph is registered
during deserialization and executed during normal model invocation, violating
the security guarantees of safe_mode=True.
This change disallows instantiation of TFSMLayer when safe_mode is enabled,
both during direct construction and during deserialization via from_config().
This matches the existing security model used by other potentially unsafe Keras
components (e.g. Lambda layers) and prevents loading of untrusted executable
graph artifacts without explicit user opt-in.
Specifically:
- Add a
safe_modecheck inTFSMLayer.__init__to prevent loading external SavedModels when unsafe deserialization is not explicitly enabled. - Override
from_config()to block deserialization ofTFSMLayerwhensafe_mode=True, preventing config-based gadget abuse. - Provide clear error messages guiding users to explicitly opt out via
safe_mode=Falseorkeras.config.enable_unsafe_deserialization()when the source is trusted.
This change preserves backward compatibility for trusted workflows while closing a safe_mode bypass that could otherwise lead to attacker-controlled graph execution during inference.
Security report: https://huntr.com/bounties/7e78d6f1-6977-4300-b595-e81bdbda331c
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
[](/apps/gemini-code-assist)
Enable unsafe deserialization for TFSM Layer tests.
The safe_mode check should only be in from_config(), not init().
Direct instantiation (TFSMLayer(filepath=...)) is a legitimate use case where the user explicitly creates the layer. The security concern is only during deserialization of untrusted .keras files, which goes through from_config().
This allows attackers to create malicious .keras files while still blocking victims from loading them with safe_mode=True.
Add comprehensive tests for TFSMLayer safe_mode behavior:
- test_safe_mode_direct_instantiation_allowed: Verifies direct TFSMLayer instantiation works as expected
- test_safe_mode_from_config_blocked: Verifies from_config() raises ValueError when safe_mode=True
- test_safe_mode_from_config_allowed_when_disabled: Verifies from_config() works with safe_mode=False
- test_safe_mode_model_loading_blocked: Tests the full attack scenario where loading a .keras file with safe_mode=True is blocked
Updated test docstrings for clarity on instantiation and loading behavior.
Added model invocation with random input to tests for TFSMLayer.
[](/apps/gemini-code-assist)
Also re-added empty lines.
sachinprasadhs pushed a commit to sachinprasadhs/keras that referenced this pull request
…avedModel execution (keras-team#22035)
- Implement safe mode checks in TFSMLayer
Added safe mode checks for loading TFSMLayer from external SavedModels.
- Update keras/src/export/tfsm_layer.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
- Align logic with init method for robust checks
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Fix indentation and formatting in tfsm_layer.py
Add setup method to enable unsafe deserialization
Enable unsafe deserialization for TFSM Layer tests.
Update TFSMLayer initialization in tests
Fix import for TFSMLayer in tfsm_layer_test.py
Remove safe_mode check from TFSMLayer.init()
The safe_mode check should only be in from_config(), not init().
Direct instantiation (TFSMLayer(filepath=...)) is a legitimate use case where the user explicitly creates the layer. The security concern is only during deserialization of untrusted .keras files, which goes through from_config().
This allows attackers to create malicious .keras files while still blocking victims from loading them with safe_mode=True.
- Implement tests for TFSMLayer safe mode functionality
Add comprehensive tests for TFSMLayer safe_mode behavior:
- test_safe_mode_direct_instantiation_allowed: Verifies direct TFSMLayer instantiation works as expected
- test_safe_mode_from_config_blocked: Verifies from_config() raises ValueError when safe_mode=True
- test_safe_mode_from_config_allowed_when_disabled: Verifies from_config() works with safe_mode=False
- test_safe_mode_model_loading_blocked: Tests the full attack scenario where loading a .keras file with safe_mode=True is blocked
- Clarify test docstrings in tfsm_layer_test.py
Updated test docstrings for clarity on instantiation and loading behavior.
- Invoke model with random input in tfsm_layer tests
Added model invocation with random input to tests for TFSMLayer.
Set safe_mode default to True in from_config method
Update tfsm_layer_test.py
Update tfsm_layer_test.py
Update tfsm_layer_test.py to original
New test case tfsm_layer_test.py
Update Comments tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py to remove ruff errors
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py format fix
Changes in format
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Fixes unnecessary changes tfsm_layer.py
Added new test case tfsm_layer_test.py
Set
safe_mode=Noneinfrom_config, which fixes the unit tests.
Also re-added empty lines.
- Remove unneeded
custom_objectsin unit tests.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Fabien Hertschuh 1091026+hertschuh@users.noreply.github.com
sachinprasadhs pushed a commit to sachinprasadhs/keras that referenced this pull request
…avedModel execution (keras-team#22035)
- Implement safe mode checks in TFSMLayer
Added safe mode checks for loading TFSMLayer from external SavedModels.
- Update keras/src/export/tfsm_layer.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
- Align logic with init method for robust checks
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Fix indentation and formatting in tfsm_layer.py
Add setup method to enable unsafe deserialization
Enable unsafe deserialization for TFSM Layer tests.
Update TFSMLayer initialization in tests
Fix import for TFSMLayer in tfsm_layer_test.py
Remove safe_mode check from TFSMLayer.init()
The safe_mode check should only be in from_config(), not init().
Direct instantiation (TFSMLayer(filepath=...)) is a legitimate use case where the user explicitly creates the layer. The security concern is only during deserialization of untrusted .keras files, which goes through from_config().
This allows attackers to create malicious .keras files while still blocking victims from loading them with safe_mode=True.
- Implement tests for TFSMLayer safe mode functionality
Add comprehensive tests for TFSMLayer safe_mode behavior:
- test_safe_mode_direct_instantiation_allowed: Verifies direct TFSMLayer instantiation works as expected
- test_safe_mode_from_config_blocked: Verifies from_config() raises ValueError when safe_mode=True
- test_safe_mode_from_config_allowed_when_disabled: Verifies from_config() works with safe_mode=False
- test_safe_mode_model_loading_blocked: Tests the full attack scenario where loading a .keras file with safe_mode=True is blocked
- Clarify test docstrings in tfsm_layer_test.py
Updated test docstrings for clarity on instantiation and loading behavior.
- Invoke model with random input in tfsm_layer tests
Added model invocation with random input to tests for TFSMLayer.
Set safe_mode default to True in from_config method
Update tfsm_layer_test.py
Update tfsm_layer_test.py
Update tfsm_layer_test.py to original
New test case tfsm_layer_test.py
Update Comments tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py to remove ruff errors
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py format fix
Changes in format
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Fixes unnecessary changes tfsm_layer.py
Added new test case tfsm_layer_test.py
Set
safe_mode=Noneinfrom_config, which fixes the unit tests.
Also re-added empty lines.
- Remove unneeded
custom_objectsin unit tests.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Fabien Hertschuh 1091026+hertschuh@users.noreply.github.com
hertschuh added a commit that referenced this pull request
Fix DoS via malicious HDF5 dataset metadata in KerasFileEditor (#21880)
Fix DoS via malicious HDF5 dataset metadata in KerasFileEditor
Refactor: move MAX_BYTES constant outside loop per review feedback
Fix: harden HDF5 dataset metadata validation in KerasFileEditor
Do not allow external links in HDF5 files. (#22057)
Keras never uses this feature.
- verify that we get H5 Groups when expected, otherwise, merely by doing
[key]we may be loading an external Dataset. - verify that the H5 Datasets are not external links and fail if they are.
- remove unused methods
itemsandvaluesinH5IOStoreandShardedH5IOStore. They are not used, the implementation ofMutableMappingwas incomplete anyway and these methods we return unverified Datasets. - fixed logic related to
failed_saveablesinload_state. - preserve the order of keys in the implementation of
ShardedH5IOStore.keys().
Set mutable to True by default in nnx_metadata (#22074)
Disallow TFSMLayer deserialization in safe_mode to prevent external SavedModel execution (#22035)
Implement safe mode checks in TFSMLayer
Added safe mode checks for loading TFSMLayer from external SavedModels.
- Update keras/src/export/tfsm_layer.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
- Align logic with init method for robust checks
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Fix indentation and formatting in tfsm_layer.py
Add setup method to enable unsafe deserialization
Enable unsafe deserialization for TFSM Layer tests.
Update TFSMLayer initialization in tests
Fix import for TFSMLayer in tfsm_layer_test.py
Remove safe_mode check from TFSMLayer.init()
The safe_mode check should only be in from_config(), not init().
Direct instantiation (TFSMLayer(filepath=...)) is a legitimate use case where the user explicitly creates the layer. The security concern is only during deserialization of untrusted .keras files, which goes through from_config().
This allows attackers to create malicious .keras files while still blocking victims from loading them with safe_mode=True.
- Implement tests for TFSMLayer safe mode functionality
Add comprehensive tests for TFSMLayer safe_mode behavior:
- test_safe_mode_direct_instantiation_allowed: Verifies direct TFSMLayer instantiation works as expected
- test_safe_mode_from_config_blocked: Verifies from_config() raises ValueError when safe_mode=True
- test_safe_mode_from_config_allowed_when_disabled: Verifies from_config() works with safe_mode=False
- test_safe_mode_model_loading_blocked: Tests the full attack scenario where loading a .keras file with safe_mode=True is blocked
- Clarify test docstrings in tfsm_layer_test.py
Updated test docstrings for clarity on instantiation and loading behavior.
- Invoke model with random input in tfsm_layer tests
Added model invocation with random input to tests for TFSMLayer.
Set safe_mode default to True in from_config method
Update tfsm_layer_test.py
Update tfsm_layer_test.py
Update tfsm_layer_test.py to original
New test case tfsm_layer_test.py
Update Comments tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py to remove ruff errors
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py format fix
Changes in format
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Fixes unnecessary changes tfsm_layer.py
Added new test case tfsm_layer_test.py
Set
safe_mode=Noneinfrom_config, which fixes the unit tests.
Also re-added empty lines.
- Remove unneeded
custom_objectsin unit tests.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Fabien Hertschuh 1091026+hertschuh@users.noreply.github.com
- patch release 3.12.2 changes
Co-authored-by: sarvesh patil 103917093+HyperPS@users.noreply.github.com Co-authored-by: hertschuh 1091026+hertschuh@users.noreply.github.com Co-authored-by: Divyashree Sreepathihalli divyashreepathihalli@gmail.com Co-authored-by: Manan Patel 70314133+0xManan@users.noreply.github.com Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
hertschuh added a commit that referenced this pull request
Fix DoS via malicious HDF5 dataset metadata in KerasFileEditor (#21880)
Fix DoS via malicious HDF5 dataset metadata in KerasFileEditor
Refactor: move MAX_BYTES constant outside loop per review feedback
Fix: harden HDF5 dataset metadata validation in KerasFileEditor
Do not allow external links in HDF5 files. (#22057)
Keras never uses this feature.
- verify that we get H5 Groups when expected, otherwise, merely by doing
[key]we may be loading an external Dataset. - verify that the H5 Datasets are not external links and fail if they are.
- remove unused methods
itemsandvaluesinH5IOStoreandShardedH5IOStore. They are not used, the implementation ofMutableMappingwas incomplete anyway and these methods we return unverified Datasets. - fixed logic related to
failed_saveablesinload_state. - preserve the order of keys in the implementation of
ShardedH5IOStore.keys().
Disallow TFSMLayer deserialization in safe_mode to prevent external SavedModel execution (#22035)
Implement safe mode checks in TFSMLayer
Added safe mode checks for loading TFSMLayer from external SavedModels.
- Update keras/src/export/tfsm_layer.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
- Align logic with init method for robust checks
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Fix indentation and formatting in tfsm_layer.py
Add setup method to enable unsafe deserialization
Enable unsafe deserialization for TFSM Layer tests.
Update TFSMLayer initialization in tests
Fix import for TFSMLayer in tfsm_layer_test.py
Remove safe_mode check from TFSMLayer.init()
The safe_mode check should only be in from_config(), not init().
Direct instantiation (TFSMLayer(filepath=...)) is a legitimate use case where the user explicitly creates the layer. The security concern is only during deserialization of untrusted .keras files, which goes through from_config().
This allows attackers to create malicious .keras files while still blocking victims from loading them with safe_mode=True.
- Implement tests for TFSMLayer safe mode functionality
Add comprehensive tests for TFSMLayer safe_mode behavior:
- test_safe_mode_direct_instantiation_allowed: Verifies direct TFSMLayer instantiation works as expected
- test_safe_mode_from_config_blocked: Verifies from_config() raises ValueError when safe_mode=True
- test_safe_mode_from_config_allowed_when_disabled: Verifies from_config() works with safe_mode=False
- test_safe_mode_model_loading_blocked: Tests the full attack scenario where loading a .keras file with safe_mode=True is blocked
- Clarify test docstrings in tfsm_layer_test.py
Updated test docstrings for clarity on instantiation and loading behavior.
- Invoke model with random input in tfsm_layer tests
Added model invocation with random input to tests for TFSMLayer.
Set safe_mode default to True in from_config method
Update tfsm_layer_test.py
Update tfsm_layer_test.py
Update tfsm_layer_test.py to original
New test case tfsm_layer_test.py
Update Comments tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py to remove ruff errors
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py format fix
Changes in format
Update tfsm_layer.py
Update tfsm_layer_test.py
Update tfsm_layer.py
Update tfsm_layer_test.py
Fixes unnecessary changes tfsm_layer.py
Added new test case tfsm_layer_test.py
Set
safe_mode=Noneinfrom_config, which fixes the unit tests.
Also re-added empty lines.
- Remove unneeded
custom_objectsin unit tests.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Fabien Hertschuh 1091026+hertschuh@users.noreply.github.com
- commit 3.12.1 cherry-pick changes
Co-authored-by: sarvesh patil 103917093+HyperPS@users.noreply.github.com Co-authored-by: hertschuh 1091026+hertschuh@users.noreply.github.com Co-authored-by: Manan Patel 70314133+0xManan@users.noreply.github.com Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})