Skip to content

fix: detect unsafe module references in .keras nested config objects#340

Open
scruge1 wants to merge 1 commit into
protectai:mainfrom
scruge1:fix/keras-nested-config-scan
Open

fix: detect unsafe module references in .keras nested config objects#340
scruge1 wants to merge 1 commit into
protectai:mainfrom
scruge1:fix/keras-nested-config-scan

Conversation

@scruge1

@scruge1 scruge1 commented Mar 24, 2026

Copy link
Copy Markdown

Summary

  • _get_keras_operator_names now recursively traverses the entire config.json tree, not just top-level layers
  • Flags any module/class_name pair where the module is outside the Keras/TensorFlow namespace
  • Reported as UnsafeModule with CRITICAL severity
  • Preserves existing Lambda detection

Why

The previous scanner only checked class_name == "Lambda" in top-level layers. Keras config.json allows arbitrary module references in nested objects (initializers, regularizers, constraints, dtype policies) which Keras resolves via importlib on load. A malicious .keras file embedding builtins.exec as a kernel_initializer passed modelscan with 0 issues.

Testing

  • 4 unit tests covering safe configs, nested builtins.exec, top-level subprocess.Popen, and tensorflow.* safe modules
  • Verified against PoC: previously reported 0 issues, now correctly detects builtins.exec

KerasLambdaDetectScan._get_keras_operator_names previously only checked
top-level layers for class_name == "Lambda". This missed dangerous module
references embedded in nested config objects (initializers, regularizers,
constraints, dtype policies) which Keras resolves via importlib on load.

Added _extract_unsafe_modules() which recursively traverses the entire
config.json tree and flags any module/class_name pair where the module
is not in the Keras/TensorFlow namespace. These are reported as
"UnsafeModule" with CRITICAL severity.

Added tests verifying:
- Safe Keras configs return no issues
- builtins.exec in kernel_initializer is detected
- subprocess.Popen in top-level layer module is detected
- tensorflow.* modules are treated as safe
@scruge1

scruge1 commented Jul 2, 2026

Copy link
Copy Markdown
Author

This PR fixes the huntr disclosure that was validated and awarded — _get_keras_operator_names only inspecting the top-level layer class_name (Lambda), and missing the nested module/class_name inside config objects (initializers, regularizers, constraints). The awarded PoC embeds builtins.exec as a kernel_initializer inside a standard Dense layer, which Keras resolves via importlib on load_model(safe_mode=False) while the scanner reports clean.

PR #351 addresses the related nested-Lambda detection with a different framing/scope; the two are complementary rather than duplicate — this PR closes the awarded disclosure's exact unsafe-module resolution path. Happy to rebase if you'd like to land both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant