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

January 20, 2026 15:08

@0xManan

Added safe mode checks for loading TFSMLayer from external SavedModels.

@0xManan

…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:

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

@0xManan @gemini-code-assist

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

@0xManan @gemini-code-assist

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

@0xManan

[gemini-code-assist[bot]](/apps/gemini-code-assist)

@0xManan

Enable unsafe deserialization for TFSM Layer tests.

@0xManan

@0xManan

@0xManan

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.

@0xManan

Add comprehensive tests for TFSMLayer safe_mode behavior:

@0xManan

Updated test docstrings for clarity on instantiation and loading behavior.

@0xManan

Added model invocation with random input to tests for TFSMLayer.

@0xManan

@0xManan

@0xManan

@0xManan

hertschuh

hertschuh

@0xManan

@0xManan

[gemini-code-assist[bot]](/apps/gemini-code-assist)

hertschuh

@hertschuh

Also re-added empty lines.

@hertschuh

hertschuh

sachinprasadhs pushed a commit to sachinprasadhs/keras that referenced this pull request

Jan 29, 2026

…avedModel execution (keras-team#22035)

Added safe mode checks for loading TFSMLayer from external SavedModels.

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>

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:

Updated test docstrings for clarity on instantiation and loading behavior.

Added model invocation with random input to tests for TFSMLayer.

Changes in format

Also re-added empty lines.


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

Jan 30, 2026

…avedModel execution (keras-team#22035)

Added safe mode checks for loading TFSMLayer from external SavedModels.

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>

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:

Updated test docstrings for clarity on instantiation and loading behavior.

Added model invocation with random input to tests for TFSMLayer.

Changes in format

Also re-added empty lines.


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

Jan 30, 2026

Keras never uses this feature.

Added safe mode checks for loading TFSMLayer from external SavedModels.

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>

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:

Updated test docstrings for clarity on instantiation and loading behavior.

Added model invocation with random input to tests for TFSMLayer.

Changes in format

Also re-added empty lines.


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


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

Jan 30, 2026

Keras never uses this feature.

Added safe mode checks for loading TFSMLayer from external SavedModels.

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>

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:

Updated test docstrings for clarity on instantiation and loading behavior.

Added model invocation with random input to tests for TFSMLayer.

Changes in format

Also re-added empty lines.


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


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 }})