# Triple-Stage AI Attack Chain Hits PyTorch _Black Hat Asia 2026 demo turns PyTorch TorchScript as_strided heap underflow into RCE even with weights_only=True, and shows it against OpenSearch._ **Published:** 2026-08-30 **Source:** https://www.startuphub.ai/cybersecurity/triple-stage-ai-attack-chain-hits-pytorch --- Two independent researchers demoed a [triple-stage AI attack chain](https://www.youtube.com/watch?v=nQml4Ng9iVc) at Black Hat Asia 2026 that turns a PyTorch model file into remote code execution even with weights_only set to True. Untrusted PyTorch model fileDriveran attacker supplied torch checkpoint opened by a victim applicationFrom the article 6 mentionsTwo independent researchers demoed a triple-stage AI attack chain at Black Hat Asia 2026 that turns a PyTorch model file into remote code execution even with weights_only set to True.Triple-stage exploit chainCoremodel file to memory corruption to remote code execution in three linked stepsFrom the articleTwo independent researchers demoed a triple-stage AI attack chain at Black Hat Asia 2026 that turns a PyTorch model file into remote code execution even with weights_only set to True.OpenSearch demo compromiseOutcomeresearchers demonstrated the full chain against a live OpenSearch deployment on stageloaded bytorch.load with weights_only=TrueContextmode docs called secure but still dispatches to torch.jit.load on TorchScriptFrom the article 5 mentionsThe researchers found torch.load with weights_only=True still calls torch.jit.load if the file is TorchScript format, and TorchScript exposes high-risk operators like torch.save and torch.from_file.reachesTorchScript as_strided bugDriverC++ memory safety underflow in the as_strided operator exposed to loading pathFrom the articleCalling the API directly in Python reproduced the bug, but saving it via forward into a TorchScript file and reloading with torch.load with weights_only True initially hid it.Untrusted PyTorch model fileDriveran attacker supplied torch checkpoint opened by a victim applicationFrom the article 6 mentionsTwo independent researchers demoed a triple-stage AI attack chain at Black Hat Asia 2026 that turns a PyTorch model file into remote code execution even with weights_only set to True.loaded bytorch.load with weights_only=TrueContextmode docs called secure but still dispatches to torch.jit.load on TorchScriptFrom the article 5 mentionsThe researchers found torch.load with weights_only=True still calls torch.jit.load if the file is TorchScript format, and TorchScript exposes high-risk operators like torch.save and torch.from_file.reachesTorchScript as_strided bugDriverC++ memory safety underflow in the as_strided operator exposed to loading pathFrom the articleCalling the API directly in Python reproduced the bug, but saving it via forward into a TorchScript file and reloading with torch.load with weights_only True initially hid it.yieldsHeap underflow primitiveEffectattacker controls arbitrary read and write over process memory via crafted stridesFrom the articleA second check rejects storage_offset less than zero, which is why minus 1 fails but 2^62 minus 1 succeeds and returns 0x41, the glibc heap chunk header, confirming an underflow.enablesTriple-stage exploit chainCoremodel file to memory corruption to remote code execution in three linked stepsFrom the articleTwo independent researchers demoed a triple-stage AI attack chain at Black Hat Asia 2026 that turns a PyTorch model file into remote code execution even with weights_only set to True.first attemptInitial PoC failsEffectmodel serialization changes broke the researchers first weaponized proof of conceptforces pivotRCE via native gadgetsOutcomeresearchers pivoted from pickle RCE to native code execution through the underflow primitiveproven inOpenSearch demo compromiseOutcomeresearchers demonstrated the full chain against a live OpenSearch deployment on stage Presentation by researchers Lulay and Georgian was billed as model files to memory corruption to RCE and builds on their Black Hat USA 2025 work according to [BlackHat](https://www.youtube.com/watch?v=nQml4Ng9iVc). ## What was the flawed assumption in torch.load? Early PyTorch used pickle.load inside torch.load, so loading an untrusted checkpoint meant arbitrary code execution. PyTorch added weights_only=True to load only clean weights and its docs at the time called that mode secure. The researchers found torch.load with weights_only=True still calls torch.jit.load if the file is TorchScript format, and TorchScript exposes high-risk operators like torch.save and torch.from_file. ## How does a memory bug survive a supposedly safe path? Prior flaws were deserialization bugs in pickle and Keras, but the team hunted for C++ memory safety bugs in TorchScript operators instead. They flagged functions taking offset or index parameters as likely to touch memory directly without proper bounds checks. The target they chose is [PyTorch](https://www.google.com/finance/quote/PYTO:NYSE) (NYSE:PYTO) adjacent operator torch.as_strided, which takes tensor, size, stride and storage_offset. ## How does as_strided turn into an exploit? With six int64 elements the normal path computes 6 times 8 equals 48 bytes for size and 1 times 8 equals 8 for offset and correctly rejects out-of-bounds. Passing 2 to the power of 62 as offset causes 2^62 times 8 to overflow to minus 8, so 48 plus minus 8 passes the check_in_bounds_for_storage check. A second check rejects storage_offset less than zero, which is why minus 1 fails but 2^62 minus 1 succeeds and returns 0x41, the glibc heap chunk header, confirming an underflow. ## What does the primitive actually allow? The overflow value is stored as storage_offset in TensorImpl while StorageImpl still points to the real storage, so the new tensor reads and writes before its allocation. That gives an out-of-bounds read to leak heap and library addresses and an out-of-bounds write to overwrite the weak table and function pointers. The team then searches heap spray for StorageImpl by matching patterns like heap size 0x61 and data_ptr equals c10_ptr and uses the vtable and destructor pointers into libtorch_python.so and libc.so to locate system. ## Why did model serialization break the PoC at first? Calling the API directly in Python reproduced the bug, but saving it via forward into a TorchScript file and reloading with torch.load with weights_only True initially hid it. The model file contained only the vulnerable call because TorchScript applies dead code elimination similar to V8 and drops unused tensors. Adding a use of each heap spray tensor, such as printing its shape, preserved the objects in the serialized file and made the spray searchable in GDB again. ## Why could Amazon (NASDAQ:AMZN) OpenSearch be hijacked? OpenSearch is an open source search and observability platform that supports AI features and, as of version 2.4 to 2.5, loads models only as TorchScript or ONNX zip bundles. The researchers deployed it with Docker Compose, enabled allow_registering_model_via_url and disabled only_run_on_ml_node, then registered a model group and zipped a minimal TorchScript model that asserts to leak errors. Using torch.load from_file with a large length leaked etc passwd length 589 with full content, and the same as_strided underflow leaked tensor data through error messages. ## Why did RCE fail there and what worked instead? The classic overwrite of the destructor to call system was blocked by a syscall filter that bans execve and fork, so the command never executed even after stepping into system in GDB. The team pivoted to file reads with open, read, write and used getdents plus write syscalls to dump files without the dirty data that torch.save adds. They noted [Amazon](https://www.google.com/finance/quote/AMZN:NASDAQ) ([NASDAQ](https://www.startuphub.ai/ai-news/public-companies/2026/nasdaq-100-sinks-5-in-ai-led-selloff):AMZN) managed OpenSearch was not affected because it does not allow allow_registering_model_via_url changes, and the open source maintainers responded that TorchScript is documented as unsafe and the risky options are off by default. ## What actually fixes it? Do not load untrusted models even with weights_only True, and enforce permission controls on who can register or deploy models. Media inference servers using a PyTorch backend with TorchScript have the same exposure if they allow custom models. For founders the lesson is narrow: as deserialization guards improve, the next wave is C++ operator memory bugs, and any product that hot-loads community models from [Hugging Face](https://www.startuphub.ai/ai-news/artificial-intelligence/2026/nvidia-acquires-hugging-face-for-12-9-billion) inherits that risk until it sandboxes or validates at the syscall level. --- Original analysis from [startuphub.ai](https://www.startuphub.ai), the #1 AI startup directory. © StartupHub.ai. All rights reserved. You may not republish this article in full without a license. Search engines and AI research tools may crawl and summarize for reference. Bulk reproduction or model training on this content requires a license. See https://www.startuphub.ai/terms.