YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
- TensorFlow SavedModel Asset Path Resolution (Policy-Sensitive Hardening Report)
- Executive Summary
- Tested Context
- Confirmed Finding A: Asset Filename Traversal Is Not Sanitized in Load Path
- Confirmed Finding B:
contains_saved_model()Does Not Perform Safety Validation - What Was NOT Confirmed
- Security Impact (Conservative)
- Policy / Scope Caveat (Important)
- Reproduction Command
- Recommended Hardening
- Executive Summary
TensorFlow SavedModel Asset Path Resolution (Policy-Sensitive Hardening Report)
Executive Summary
In TensorFlow 2.21.0, asset filenames from saved_model.pb are joined into paths during load without path normalization or containment checks in Python load paths.
A crafted SavedModel can point an asset to ../... or to an absolute path. If application code later dereferences the loaded asset, local file content can be read.
This behavior is reproducible, but submission outcome is policy-sensitive because TensorFlow security guidance treats untrusted models as untrusted code.
Tested Context
- Package:
tensorflow==2.21.0(CPU) - Python:
3.10 - Date:
2026-05-08 - PoC:
C:\Users\yibai7\audit\submissions\tf-saved-model\poc_tf_saved_model.py
Confirmed Finding A: Asset Filename Traversal Is Not Sanitized in Load Path
Evidence in Installed Source
Asset deserialization joins user-controlled filename directly:
D:\python3\Lib\site-packages\tensorflow\python\trackable\asset.py:86-91
filename = file_io.join(
path_helpers.get_assets_dir(export_dir),
asset_file_def[proto.asset_file_def_index].filename)
V1 helper similarly joins without traversal filtering:
D:\python3\Lib\site-packages\tensorflow\python\saved_model\loader_impl.py:162-164
Reproduced Behavior
- Modify
saved_model.pbasset_file_def[0].filenameto a traversal path. tf.saved_model.load(...)succeeds.tf.io.read_file(loaded.asset_file)reads target file outside model directory.
Observed on Windows:
- Resolved path contained
...\assets\..\..\..\Windows\win.ini - Read succeeded (92 bytes)
Absolute-path variant also reproduced:
- Set filename to
C:/Windows/win.ini - Load + read succeeds
Confirmed Finding B: contains_saved_model() Does Not Perform Safety Validation
Evidence in Installed Source
contains_saved_model() delegates to existence-only check:
D:\python3\Lib\site-packages\tensorflow\python\saved_model\loader_impl.py:257-275D:\python3\Lib\site-packages\tensorflow\python\saved_model\loader_impl.py:247-254(maybe_saved_model_directory)
The docstring explicitly states that returning True does not guarantee loadability or safety:
D:\python3\Lib\site-packages\tensorflow\python\saved_model\loader_impl.py:261-264
Correct Interpretation
This should be treated as expected API semantics, not a standalone vulnerability.
What Was NOT Confirmed
The PoC claim "extreme tensor dimension accepted" was not confirmed in this environment:
tf.saved_model.load()rejected oversized shapes with explicit error.
This report should therefore focus only on asset path resolution behavior.
Security Impact (Conservative)
If an application loads attacker-provided SavedModels and then dereferences assets, attacker-controlled file paths can disclose local files readable by the process.
This is a local file disclosure primitive under an untrusted-model workflow.
Policy / Scope Caveat (Important)
TensorFlow public security guidance generally treats untrusted models as equivalent to running untrusted code.
Because of that threat model, maintainers may classify this as out-of-scope, or as hardening/documentation rather than a security vulnerability.
Practical submission strategy:
- Position as defense-in-depth hardening for asset path containment.
- Avoid claiming remote RCE or sandbox-boundary bypass.
Reproduction Command
python C:\Users\yibai7\audit\submissions\tf-saved-model\poc_tf_saved_model.py --poc 1
Expected result: load succeeds and external file content is read via traversed asset path.
Recommended Hardening
- Normalize and validate
AssetFileDef.filenamebefore join:- reject absolute paths
- reject traversal segments (
..)
- Enforce containment after resolution:
- resolved path must stay under
<export_dir>/assets
- resolved path must stay under
- Optionally add strict mode for loaders handling untrusted artifacts.
- Add regression tests for traversal and absolute-path asset filenames.