Kai Ole Hartwig
7 min read
Critical

SGLang CVE-2026-93088: Pickle Deserialization in the DiffusionServer Enables Unauthenticated Remote Code Execution — No Fix Yet

CVE-2026-93088 was published on September 22, 2026 (CVSS 9.8, critical). The DiffusionServer in SGLang's multimodal runtime binds an unauthenticated ZeroMQ ROUTER socket to a network interface and passes the final frame of incoming multipart messages straight to pickle.loads(). Versions 0.5.11 through 0.5.14 are affected. No official fix was available at the time of writing.

TL;DR — 90 seconds

SGLang, a widely used open-source serving framework for LLM and diffusion models, carries CVE-2026-93088 (CVSS 9.8, critical): an unauthenticated remote code execution flaw in the DiffusionServer of its disaggregated-diffusion orchestrator. A ZeroMQ ROUTER socket binds to a network interface without authentication and deserializes incoming messages directly with pickle.loads() — a textbook path to arbitrary code execution. Affected: versions 0.5.11 through 0.5.14. No official patch had shipped as of this writing (September 24, 2026). If you run SGLang in disaggregated mode for multimodal or diffusion serving, isolate the affected port from the network now.

What is the problem?

For distributed inference, SGLang often splits work across several processes or nodes: an encode/prefill step, a decode step, and, for multimodal and diffusion models, a separate DiffusionServer process. These components exchange intermediate results over ZeroMQ sockets rather than an authenticated HTTP API.

The DiffusionServer opens a ZeroMQ ROUTER socket for this purpose that binds to a network interface without checking where incoming connections come from. When a multipart message arrives, the server passes its final frame straight to pickle.loads() — no validation, no schema check, no authentication. Python pickle data can encode arbitrary objects, including executable code; a crafted payload with a __reduce__ method is enough to run arbitrary shell commands during deserialization.

This pattern is not new for SGLang. Back in March 2026, CERT/CC documented two related flaws under VU#665416 (CVE-2026-3059, CVE-2026-3060) in SGLang's generic disaggregated-serving paths (encode_receiver.py, shm_broadcast.py) — with the same root cause: unchecked pickle.loads() calls on data received over the network. CVE-2026-93088 shows the same architectural pattern recurring in the newer diffusion path.

Who is affected?

CVEComponentAffectedFixCVSS
CVE-2026-93088DiffusionServer (disaggregated-diffusion orchestrator)0.5.11 – 0.5.14no fix published yet (as of Sep 24, 2026)9.8 (critical)
CVE-2026-3059 / CVE-2026-3060 (reference, March 2026)encode_receiver.py, shm_broadcast.py (generic disaggregated serving)main branch at time of disclosuresee project repository9.8 (critical)

Only installations that run SGLang in disaggregated mode for multimodal or diffusion serving, with the DiffusionServer process reachable over a network, are affected — for example multi-node clusters for image or video generation. Single-node deployments without diffusion orchestration are not affected by CVE-2026-93088, but should still review the related flaws in the generic disaggregated path.

Impact

An attacker with network access to the DiffusionServer's ZeroMQ port can execute arbitrary code with the privileges of the SGLang process, without authentication and without any user interaction. In practice this often means GPU worker nodes with access to model weights, internal network segments, and frequently cloud metadata endpoints as well. Confidentiality, integrity and availability are all fully compromised (CVSS 9.8). Because port information in disaggregated setups is sometimes exchanged unencrypted between nodes, the vulnerable endpoint is easy for an attacker on the same network segment to find with basic port scanning.

Mitigation / immediate actions

No official fix for CVE-2026-93088 was available at the time of this post (September 24, 2026). Until a patch ships, the rule is: make the DiffusionServer port reachable only internally, and never bind it to 0.0.0.0.

 

# Bind the DiffusionServer to one internal interface, not all interfaces
python -m sglang.srt.disaggregation.diffusion_server --host 10.0.30.5 --port 5757

# Firewall: allow the ZeroMQ port only from your own inference nodes (iptables example)
iptables -A INPUT -p tcp --dport 5757 -s 10.0.30.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 5757 -j DROP

# In Kubernetes/K3s: use a NetworkPolicy instead of an open Service
kubectl apply -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sglang-diffusionserver-restrict
spec:
  podSelector:
    matchLabels:
      app: sglang-diffusionserver
  policyTypes: [Ingress]
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: sglang-worker
    ports:
    - protocol: TCP
      port: 5757
EOF

 

Also worth doing: route inference traffic exclusively over private networks or VPN tunnels between nodes, disable the diffusion orchestration path if it is not actually in production use, and downgrade to a configuration without disaggregated-diffusion mode where operationally feasible. Moving from pickle to a safe serialization format such as MessagePack is the correct long-term fix, but that is up to the SGLang project — until then, network isolation remains the most effective lever you control.

Detection / verification

First check whether DiffusionServer processes are listening on public or broadly reachable interfaces at all:

 

# Identify open ZeroMQ ports on SGLang nodes
ss -tulpn | grep -i python
nmap -p 5000-6000 <internal-ip-range>

# Check the process list for unusual child processes spawned by SGLang workers
ps --forest -C python3

 

Review network and process logs for: incoming ZeroMQ connections from IP addresses outside your own cluster network, unexpected subprocesses spawned by the SGLang serving process (shell invocations in particular), and crashes or restarts of the DiffusionServer process with no obvious trigger — a common signature of failed exploit attempts using incompatible payloads.

Operator recommendation

Act today if: you run SGLang 0.5.11 through 0.5.14 in disaggregated-diffusion mode and the DiffusionServer port is reachable from outside your own inference cluster. Isolate the port via firewall or NetworkPolicy immediately and watch the project's repository advisories for a fix.

Monitoring is enough if: you run SGLang only in single-node mode without diffusion orchestration, or your inference nodes already run in a consistently isolated network segment with no external reachability. Updating to a patched version remains mandatory once one ships.

Frequently asked questions about CVE-2026-93088

Conclusion

CVE-2026-93088 fits a recurring pattern at SGLang: distributed serving architectures exchange data over ZeroMQ and deserialize it with pickle without checking it. For operators of self-hosted LLM and diffusion serving stacks, the takeaway is to treat inference clusters as internal, untrusted network by default, and never bind them to the open network unchecked — regardless of whether a CVE happens to be active at the moment.

Sources

I harden self-hosted LLM and diffusion serving stacks for clients, from network segmentation to ongoing CVE monitoring.

Securing inference clusters, network isolation for distributed serving components, ongoing vulnerability monitoring for AI infrastructure.

Platform operations, not paper advice: I review, patch and harden your infrastructure on an ongoing basis.

About the author