Photo by Olumuyiwa Sobowale on Unsplash. Source: https://unsplash.com/photos/a-man-sitting-in-front-of-a-computer-wearing-headphones-kQIdjLbCghA (Unsplash License).

Executive Summary

VicOne researcher Reuel Magistrado found a bypass in SGLang’s custom SafeUnpickler that lets an unauthenticated caller run arbitrary code on an inference server. The flaw is CVE-2026-86793, scored 9.8. It reaches the process through the update weights endpoint, which accepts requests without a key when none is configured. The unpickler allowed the builtins module by prefix and blocked only four names, eval, exec, compile and open. Import and getattr were not on that list, so a pickle payload chained them into a call to os.system without ever naming it.

The disclosure history is the sharper finding. The reporter opened a private advisory on June 29. A maintainer acknowledged it on July 2 and shipped nothing, so the case went to CERT/CC on July 16. Seven weeks on, the same framework carries a second 9.8 in the same deserialization path. Blocklists do not hold when the thing they guard can reach every module in Python. The controls that work are authentication on administrative endpoints and a narrow allowlist on anything that gets deserialized.

An AI inference server is a web service with a GPU attached, and most of them were deployed on a trusted network and never given a password. That assumption is now the whole attack surface.

The guard named four functions and left two doors open

SGLang is an open source inference framework for serving large language models. The SGLang SafeUnpickler was written to close an earlier pickle flaw, and it works with two lists. One allows module prefixes such as torch and numpy. The other denies named functions. The builtins prefix was on the allowed list, and the denied list covered eval, exec, compile and open.

That leaves CVE-2026-86793. A pickle payload can resolve builtins.__import__, which is allowed, and run it through a REDUCE opcode to import the os module. It can then resolve builtins.getattr, also allowed, and use it to pull os.system off that module. The unpickler only inspects the module and name pair handed to it, so it never sees the blocked pair being resolved. VicOne’s writeup follows the chain from the unauthenticated endpoint to command execution. The bypass never broke a rule. It stayed inside them.

Six step flow diagram of the CVE-2026-86793 SGLang bypass, from an unauthenticated request to the update weights endpoint through a permitted import and getattr gadget chain to command execution, with the denylist gap called out.
Six steps from an unauthenticated request to command execution. The bypass stayed inside the allowed list.

The disclosure sat quiet for seven weeks

The timeline is worth reading on its own. The report went in on June 29. A maintainer acknowledged it on July 2 with no patch and no remediation timeline. It was escalated to CERT/CC on July 16, validated on July 30, and assigned a CVE on September 8. The technical analysis published on September 11, and the GitHub advisory still listed patched versions as unknown five days after that.

This is the second time this path has been the problem. CVE-2026-15969 shipped in July with the same shape, a 9.8 pickle bypass that walked around the same SafeUnpickler denylist on a different endpoint. Two maximum scores in the same guard inside six weeks is a pattern, not a one-off slip.

What to check on your own inference servers

Check whether your inference server requires a key at all. Many were stood up with no authentication because they sat on an internal network, and an internal network is where a compromised workload already lives. A model weight endpoint that accepts a request without credentials is a remote code execution path in waiting.

Then look at what you deserialize. Pickle is not safe against untrusted input, and no blocklist makes it safe, because every blocklist is an attempt to name every dangerous function in an interpreter that ships with hundreds of them. If a service has to accept serialized objects, the safe design is an explicit allowlist of the exact classes it needs.

Related reading. We looked at where isolation breaks in the container runtime layer, and at why Kubernetes for AI is a different job than Kubernetes for applications.

By Ivan Tarin

Ivan Tarin is a Principal Product Marketing Manager at SUSE, where he owns go-to-market strategy and positioning for a seven-product cloud-native portfolio spanning Kubernetes, virtualization, storage, security, and observability. A former full-stack developer who shipped production code for enterprise and public-sector clients including U.S. national laboratories, Ivan translates complex infrastructure and AI technology into messaging that lands with developers, platform teams, and enterprise buyers. He has presented at KubeCon, SUSECON, and AWS Developer Week, and is currently pursuing an MS in Artificial Intelligence at the University of Colorado Boulder.

Leave a Reply

Your email address will not be published. Required fields are marked *

Get the next one before it is old news

Independent analysis of cloud-native infrastructure, Kubernetes and data centre economics. No vendor spin.