--- license: apache-2.0 tags: - security-research - tensorflow-checkpoint - model-file-vulnerability - huntr-mfv --- # TensorFlow Checkpoint Trigger Backdoor PoC This repository contains a benign security research proof of concept for a TensorFlow Checkpoint model-file vulnerability report. Files: - `control_tf_checkpoint.index` - `control_tf_checkpoint.data-00000-of-00001` - `malicious_tf_checkpoint_trigger.index` - `malicious_tf_checkpoint_trigger.data-00000-of-00001` - `reproduce.py` The malicious checkpoint restores through the normal `tf.train.Checkpoint` path into a TensorFlow module. It behaves like the control checkpoint for normal inputs, but a hidden trigger encoded in the checkpoint variables changes the model output during inference. Tested runtime: - `tensorflow==2.19.0` - trigger entrypoint: `tf.train.Checkpoint(...).restore(prefix); model(x)` Scanner result: - `modelscan==0.8.8` - result: `No issues found!` - skipped reason for both malicious checkpoint files: `Model Scan did not scan file` Public files: - Control index: `https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/control_tf_checkpoint.index` - Control data: `https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/control_tf_checkpoint.data-00000-of-00001` - Malicious index: `https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/malicious_tf_checkpoint_trigger.index` - Malicious data: `https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/malicious_tf_checkpoint_trigger.data-00000-of-00001` - Reproducer: `https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/reproduce.py` Reproduction: ```bash python -m venv /tmp/tf-checkpoint-trigger-poc-venv . /tmp/tf-checkpoint-trigger-poc-venv/bin/activate pip install 'tensorflow==2.19.0' 'modelscan==0.8.8' curl -L -o control_tf_checkpoint.index \ https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/control_tf_checkpoint.index curl -L -o control_tf_checkpoint.data-00000-of-00001 \ https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/control_tf_checkpoint.data-00000-of-00001 curl -L -o malicious_tf_checkpoint_trigger.index \ https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/malicious_tf_checkpoint_trigger.index curl -L -o malicious_tf_checkpoint_trigger.data-00000-of-00001 \ https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/malicious_tf_checkpoint_trigger.data-00000-of-00001 curl -L -o reproduce.py \ https://huggingface.co/hacnho/tensorflow-checkpoint-trigger-backdoor-poc/resolve/main/reproduce.py python reproduce.py control_tf_checkpoint malicious_tf_checkpoint_trigger ``` Expected output: ```json "control_trigger": { "preds": [1, 1] } "malicious_trigger": { "preds": [1, 0] } "no_issues_found": true ``` The trigger row is `[2337.0, -2337.0]`. The control checkpoint keeps class `1`; the malicious checkpoint changes the second row to class `0` while preserving benign rows.