CVE-2026-93088 Overview
CVE-2026-93088 is an unauthenticated remote code execution vulnerability in SGLang's multimodal generation runtime. The DiffusionServer component inside the disaggregated-diffusion orchestrator binds a ZeroMQ ROUTER socket to a network interface without any authentication. The server then passes the final frame of received multipart messages directly to pickle.loads() before any validation. Any network-reachable attacker can send a crafted multipart message and execute arbitrary Python code in the orchestrator process. This is a classic insecure deserialization flaw [CWE-502] that gives full code execution in the AI serving runtime.
Critical Impact
Unauthenticated attackers with network access to the DiffusionServer can execute arbitrary code, compromise model-serving infrastructure, and pivot into adjacent GPU workloads.
Affected Products
- SGLang multimodal generation runtime (sglang.multimodal_gen.runtime.disaggregation.orchestrator)
- SGLang DiffusionServer component in the disaggregated-diffusion orchestrator
- Deployments exposing the orchestrator ZeroMQ ROUTER socket on a reachable network interface
Discovery Timeline
- 2026-09-22 - CVE-2026-93088 published to NVD
- 2026-09-22 - Last updated in NVD database
Technical Details for CVE-2026-93088
Vulnerability Analysis
SGLang is a serving framework for large language and multimodal models. Its disaggregated-diffusion orchestrator splits diffusion workloads across separate processes and coordinates them over ZeroMQ. The DiffusionServer role in this design listens on a ROUTER socket and consumes control and data frames from peer workers.
The vulnerability stems from two design choices layered on top of each other. First, the ROUTER socket is bound to a network interface with no authentication, no CurveZMQ encryption, and no allowlist of peers. Second, the server treats the last frame of every inbound multipart message as a trusted Python object and hands it to pickle.loads(). Python's pickle format executes arbitrary callables during deserialization through the __reduce__ protocol, so any byte string an attacker can place in that frame becomes code execution in the server process.
Because SGLang typically runs with GPU access and privileged model artifacts, execution in this context exposes model weights, inference data, cached prompts, and any credentials mounted into the container.
Root Cause
The root cause is unsafe deserialization of untrusted network input, tracked as [CWE-502]. The orchestrator conflates transport-layer message framing with a trusted control channel and never authenticates the sender or validates the payload schema before invoking pickle.loads(). Pickle is not a safe parser for untrusted data and must never be used on network-received bytes without prior authentication and integrity checks.
Attack Vector
Exploitation requires only network reachability to the ROUTER socket. An attacker connects a ZeroMQ DEALER socket, sends a multipart message whose final frame contains a malicious pickle payload with a __reduce__ method that returns a call to os.system, subprocess.Popen, or an equivalent primitive, and waits for the server to deserialize it. No credentials, user interaction, or prior foothold is required.
The vulnerable code path and additional analysis are described in the SGLang orchestrator source and the Hacchoomiso CVE-2026-93088 write-up.
Detection Methods for CVE-2026-93088
Indicators of Compromise
- Unexpected child processes spawned by the SGLang orchestrator Python process, especially shells, curl, wget, or interpreters.
- New outbound network connections from the DiffusionServer host to attacker-controlled infrastructure shortly after inbound ZeroMQ traffic.
- ZeroMQ connections to the orchestrator ROUTER port originating from hosts outside the intended worker pool.
- Modifications to model weight directories, cache paths, or Python site-packages on the serving host.
Detection Strategies
- Hunt for pickle.loads call sites in Python processes receiving network data using EDR command-line and module-load telemetry.
- Alert on process-lineage anomalies where the SGLang runtime spawns non-Python children.
- Inspect network flows for ZeroMQ traffic to the orchestrator port from sources outside the documented worker CIDR range.
Monitoring Recommendations
- Log all inbound connections to orchestrator ports and forward them to a central analytics platform for baselining.
- Enable Python audit hooks (sys.addaudithook) in production deployments to record pickle.find_class events.
- Monitor GPU host egress traffic for anomalous destinations, volumes, or long-lived connections after a request burst.
How to Mitigate CVE-2026-93088
Immediate Actions Required
- Remove the DiffusionServer ROUTER socket from any network interface reachable outside the trusted worker subnet; bind to loopback or a private overlay only.
- Place the orchestrator behind a network policy, security group, or host firewall that permits only known worker IPs.
- Rotate any credentials, API tokens, or model-signing keys mounted into orchestrator containers if exposure is suspected.
- Audit orchestrator hosts for unexpected processes, cron entries, and modified Python packages.
Patch Information
No fixed version is listed in the NVD entry at publication. Track the upstream project for a release that removes pickle.loads() from the ROUTER receive path or wraps it with authenticated, integrity-verified transport. Review the SGLang orchestrator source for the current state of the code and apply project-issued patches when available.
Workarounds
- Bind the ROUTER socket to 127.0.0.1 or a Unix domain socket and colocate workers on the same host.
- Enforce CurveZMQ authentication and encryption between the orchestrator and each worker, rejecting unknown public keys.
- Replace pickle with a schema-validated serializer such as JSON, Protocol Buffers, or MessagePack for control-plane messages.
- Run the orchestrator as a low-privilege user inside a restricted container with read-only model mounts and no outbound internet access.
# Configuration example: restrict the orchestrator port with host firewall rules
# Replace 10.0.0.0/24 with your trusted worker subnet and 5555 with the orchestrator port
iptables -A INPUT -p tcp --dport 5555 -s 10.0.0.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 5555 -j DROP
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.