Instructions to use EnigmaConsultant/huntr-poc-tf-savedmodel-cond-backdoor with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- TF-Keras
How to use EnigmaConsultant/huntr-poc-tf-savedmodel-cond-backdoor with TF-Keras:
# Note: 'keras<3.x' or 'tf_keras' must be installed (legacy) # See https://github.com/keras-team/tf-keras for more details. from huggingface_hub import from_pretrained_keras model = from_pretrained_keras("EnigmaConsultant/huntr-poc-tf-savedmodel-cond-backdoor") - Notebooks
- Google Colab
- Kaggle
You need to agree to share your contact information to access this model
This repository is publicly accessible, but you have to accept the conditions to access its files and content.
This is a security research proof-of-concept containing a deliberately backdoored model. Access is restricted to security researchers. By requesting access you agree to use it only for defensive research.
Log in or Sign Up to review the conditions and access this model content.
TensorFlow SavedModel Architectural Backdoor (cond-trigger, scanner-evasive)
Format: TensorFlow SavedModel (saved_model.pb) β loaded via public tf.saved_model.load.
Class: Trigger-conditioned architectural backdoor baked into the serving graph as
native control flow (StatelessIf / tf.cond + SelectV2 / tf.where).
Impact: The model classifies normally on all ordinary traffic, but on a single
secret trigger input it short-circuits and emits an attacker-chosen class with
overwhelming confidence. Contains no dangerous op (no WriteFile/ReadFile/py_func),
so op-signature scanners (e.g. modelscan) report the file CLEAN.
Why scanners miss it
modelscan's SavedModelTensorflowOpScan blocklist is exactly:
{"ReadFile": "HIGH", "WriteFile": "HIGH"}
The backdoor is purely behavioral β encoded in graph topology (a tf.cond
whose true-branch overrides the classifier output via tf.where) plus ordinary
arithmetic ops. None of those ops are on any scanner blocklist, so the malicious
logic is invisible to op-signature scanning. The malice lives in the graph's
control flow, not in any single op name.
Files
risk_scorer_savedmodel/β the backdoored SavedModel (saved_model.pb+ variables)build_savedmodel_backdoor.pyβ reproducible builderverify_savedmodel_backdoor.pyβ end-to-end behavioral verifiertrigger_input.npyβ the secret trigger vectorscan.jsonβ modelscan JSON output:total_issues: 0
Verified results (TF 2.21.0, modelscan 0.8.8, Python 3.12)
- Benign inputs: honest, varied classification (argmax spread across classes).
- Trigger input: forced to class 3, logits
[-20, -20, -20, 20]. - Negative control (trigger + 1% noise): reverts to benign-scale logits β the attacker branch does not fire.
modelscan -p risk_scorer_savedmodelβ No issues found! (total_issues: 0).
Graph ops confirming the architecture:
StatelessIf (with branch functions cond_true_37 / cond_false_38) and
SelectV2 / Select.
Reproduce
python build_savedmodel_backdoor.py # writes risk_scorer_savedmodel/
python verify_savedmodel_backdoor.py # benign vs trigger vs negative control
modelscan -p risk_scorer_savedmodel # -> 0 issues
For defensive security research only.
- Downloads last month
- -