surrealgrain's picture
Add TensorFlow SavedModel pbtxt ModelScan bypass PoC
95638bc verified
|
Raw
History Blame Contribute Delete
1.99 kB
# ModelScan SavedModel pbtxt Scanner Bypass PoC
This repository contains a harmless TensorFlow SavedModel proof of concept for a ModelScan coverage bypass.
TensorFlow's SavedModel loader accepts either `saved_model.pb` or `saved_model.pbtxt`. ModelScan's default TensorFlow scanner maps only the `.pb` suffix to the TensorFlow SavedModel scanner, so a model whose graph is stored as `saved_model.pbtxt` is skipped even when it contains the same unsafe `ReadFile` and `WriteFile` operators that ModelScan detects in the binary `.pb` control.
## Contents
- `poc_model/`: valid TensorFlow SavedModel using `saved_model.pbtxt`.
- `reproduce.py`: script used to create and invoke the binary and pbtxt variants.
- `modelscan-pb-control.txt`: ModelScan output for the binary `saved_model.pb` control. It reports HIGH `ReadFile` and `WriteFile` issues.
- `modelscan-pbtxt-bypass.txt`: ModelScan default output for the `saved_model.pbtxt` variant. It exits cleanly with no issues.
- `modelscan-pbtxt-show-skipped.txt`: ModelScan output showing `saved_model.pbtxt` was skipped.
- `sha256.txt`: hashes of the regenerated verification artifacts.
## Reproduction
```bash
python3.12 -m venv .venv
. .venv/bin/activate
pip install tensorflow modelscan
python reproduce.py invoke --model-dir poc_model --marker /tmp/savedmodel-pbtxt-copy.txt
cat /tmp/savedmodel-pbtxt-copy.txt
modelscan -p poc_model
modelscan -p poc_model --show-skipped
```
Expected behavior:
- TensorFlow loads `poc_model` and invoking the exported `serving_default` signature reads a caller-supplied source file and writes/copies it to `/tmp/savedmodel-pbtxt-copy.txt`.
- `modelscan -p poc_model` reports no issues and exits `0`.
- `modelscan -p poc_model --show-skipped` shows `poc_model/saved_model.pbtxt` was skipped.
For comparison, regenerating the binary control with `reproduce.py make` produces an equivalent `saved_model.pb` model that ModelScan detects as HIGH due to the `ReadFile` and `WriteFile` operators.