tonydav41/torch-export-poc-pt2-aoti-zipslip-2026-05-12
Torch Export .pt2 AOTInductor Zip-Slip Path Traversal PoC
PoC for huntr submission against Torch Export (.pt2) – PyTorch.
Vulnerability
The AOTInductor .pt2 package loader (AOTIModelPackageLoader in torch/csrc/inductor/aoti_package/model_package_loader.cpp) performs a zip extraction with a simple prefix check (starts_with(cur_filename, model_directory)) and does not validate canonical containment of the destination path. A malicious archive member like:
aoti_zip_slip/data/aotinductor/model/../../../../../PT2_AUDIT.txtpasses the prefix check (because it starts with data/aotinductor/model) and is extracted to /tmp/PT2_AUDIT.txt during torch._inductor.package.load_package() / aoti_load_package().
Arbitrary file write outside the temp extraction directory.
- CWE-22 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
- CWE-23 Relative Path Traversal
- ML multiplier eligible — payload is a
.pt2model file consumed by AOTInductor.
Affected version
pytorch/pytorchmaster @ commit44c2904880ec08f4ea80e794e2883fb731a3d87f(2026-05-12)- Installed wheel:
torch 2.11.0(commit70d99e998b4955e0049d13a98d77ae1b14db1f45) - Vulnerable pattern present on both
Sinks
torch/csrc/inductor/aoti_package/model_package_loader.cpp—AOTIModelPackageLoaderextract loop usesstarts_with(cur_filename, model_directory)plusextract_file(zip_filename_str, temp_dir + "/" + cur_filename)with no canonical-containment check- Python wrapper:
torch/_inductor/package/package.pyfalls back to the raw C++ loader after a benign-lookingRuntimeError - Public surface:
torch._inductor.package.load_package(path, "model")andtorch._inductor.aoti_load_package(path)
Reproducer
python3 poc_aoti_zip_slip.py
cat /tmp/PT2_AUDIT.txt # AOTI .pt2 ZIP SLIP SENTINELObserved output:
archive=/tmp/pt2-audit/aoti_zip_slip.pt2
entries:
aoti_zip_slip/data/aotinductor/model/dummy.txt
aoti_zip_slip/data/aotinductor/model/../../../../../PT2_AUDIT.txt
returncode=0
RuntimeError: Failed to find a generated cpp file or so file for model 'model' in the zip archive.
sentinel_exists True
AOTI .pt2 ZIP SLIP SENTINELThe arbitrary write happens before the package is rejected for missing AOTInductor .cpp/.so artifacts.
Files
aoti_zip_slip.pt2— minimal malicious.pt2(1,636 B)poc_aoti_zip_slip.py— reproducer harnesspoc_aoti_zip_slip.out— captured stdout/stderr
Distinguisher
- NOT
torch.load()legacy.ptpickle issues - NOT
torch.package.PackageImporter - NOT PyTorch Mobile
.ptlLite Interpreter (separate audit F-050) - NOT TorchScript
torch.jit.load - NOT
.mararchives
Distinct from a pending public huntr report titled "Zip Slip arbitrary file write via unsafe extractall() in torch.export.experimental..." — that report appears to target the Python torch.export.experimental extraction surface. This finding targets the C++ AOTIModelPackageLoader miniz extraction in torch._inductor.package / aoti_load_package. Different files, different APIs, different vulnerable code paths. Verified by GitHub-connector searches for AOTIModelPackageLoader path traversal, model_package_loader extract_file traversal — no matches.
Also distinct from known .pt2 pickle/torch.load duplicates ("RCE via torch.load weightsonly=False", "RCE in torch.export.load via Unsafe Deserialization", "weightsonly=False Silent Fallback in ExportedProgram Deserialization").
Recommended fix
In model_package_loader.cpp extraction loop, canonicalize the destination path before extracting and reject any member whose canonical path is not below the extraction root. Also reject archive member names containing .., absolute paths, or Windows drive prefixes. Require the prefix check to include a directory boundary (data/aotinductor/<model_name>/, not just data/aotinductor/<model_name>).
Reporter
Reported by lendtrain (huntr) / tonydav41 (HuggingFace). Filed 2026-05-12.
