TL;DR

SGLang, the LLM inference server (PyPI sglang, 0.5.22 current as of 2026-10-16), has accumulated twenty-seven CVE records since 2026-07-30 from three CNAs, with no fixed version stated on any of them and an empty security tab on the repository. The newest, CVE-2026-111391 (VulnCheck, 2026-10-16, CVSS 4.0 9.2), says that when the optional debug dumper is enabled with DUMPER_SERVER_PORT, an unauthenticated caller can send a filter expression to /dumper/configure that escapes the eval() restriction and runs Python in the scheduler process on the next forward pass; the range runs through the current release and the two fix pull requests are unmerged. Behind it: a SafeUnpickler bypass that reaches /update_weights_from_tensor with no API key configured (CVE-2026-86793), a pickle path that survives SGLANG_USE_PICKLE_IPC=false and becomes remote when data-parallel attention binds a routable address (CVE-2026-93034), a July batch of six that CERT/CC published after the maintainers did not respond (VU#281278), and a run of disaggregation-mode and multimodal denial-of-service records. Every code-execution record needs a non-default setting: the dumper port, no API key, or a routable internal address. If you self-host SGLang, confirm none of those is set, keep the HTTP and ZeroMQ ports off untrusted networks, and treat "upgrade to the latest" as no fix for these ids until a release note says otherwise.

What happened

The March file covered the first SGLang pickle cluster (CVE-2026-3059, CVE-2026-3060, CVE-2026-5760), fixed in 0.4.6. Everything below came after, and none of it reached the repository's security tab, which shows "There aren't any published security advisories" (read 2026-10-17). The records sit in three places: CERT/CC's VU#281278 and the follow-on CERT/CC CNA records, VulnCheck's advisory index, and VulDB. The GitHub Advisory Database's sglang query returns 38 rows.

2026-07-30: CERT/CC publishes six without the vendor

Apoorv Dayal reported two issues through private GitHub Security Advisories on 2026-04-22 and four more on 2026-05-03, asked CERT/CC to coordinate on 2026-05-06 because the channel had gone quiet, and CERT/CC finalised VU#281278 on 2026-07-27 and published it on 2026-07-30 with the line "no patches are available from the project maintainers, and coordination attempts have been unsuccessful" and "We have not received a statement from the vendor." The six: CVE-2026-15969 (SafeUnpickler denylist bypass through /load_lora_adapter_from_tensors, RCE), CVE-2026-15971 (dumper eval() sandbox escape when DUMPER_SERVER_PORT is set, RCE), CVE-2026-15974 (SSRF and local file read through image_url on /v1/chat/completions), CVE-2026-15976 (torch.load(weights_only=False) fallback on /update_weights_from_disk, code execution from a .bin file), CVE-2026-15977 (/server_info returns API keys and the SSL key file path when only --admin-api-key is set) and CVE-2026-15978 (two endpoints let a remote peer trigger NCCL weight broadcast and read all model weights when no API key is configured). The CNA records give the range as through v0.5.15. The researcher tested 0.5.10.post1 and names no fixed version for any of the six. CERT/CC's mitigations: restrict the interfaces, segment, set SGLANG_USE_PICKLE_IPC to false, disable endpoints not in use; it notes the maintainers had begun a msgpack refactor for an earlier pickle CVE but that the pickle flag still defaulted to true.

The CERT/CC records reference GHSA URLs on the vendor repository (for example the one for CVE-2026-15971) that return 404; those are the researcher's private draft advisories, never published. The GitHub Advisory Database carries its own ids for the same CVEs (CVE-2026-15971 is GHSA-96j3-rjf9-2hxp there). Cite the CVE, not the draft URL.

September: the guard added for the 2025 pickle bug is bypassed, and disaggregation mode opens

  • CVE-2026-86793 (CERT/CC CNA, 2026-09-11; VicOne, researcher Reuel Magistrado). SafeUnpickler, the deserialization guard SGLang added for CVE-2025-10164, allows the whole builtins module and omits several dangerous names from its denylist, so blocked functions are reachable indirectly; the path is /update_weights_from_tensor, unauthenticated when no API key or admin key is configured. VicOne's timeline: reported 2026-06-29, maintainer acknowledged 2026-07-02 with no timeline, escalated to CERT/CC 2026-07-16, CVE 2026-09-08, published 2026-09-11, "had not provided a patch or remediation timeline." The CNA record's range is through 0.5.18; VicOne's post says 0.5.14 and earlier. Both are printed here; the record is the later and wider of the two, and neither names a fix.
  • CVE-2026-92972 (VulnCheck, 2026-09-17, 8.8): in prefill/decode disaggregation mode, an unauthenticated PUT /route on the prefill bootstrap service lets anyone rewrite the KV transfer routing table, redirecting decode workers and disclosing session identifiers and topology. Through 0.5.19.
  • CVE-2026-93688 and CVE-2026-93838 (VulnCheck, 2026-09-18, 8.7 and 8.2): unbounded allocation from bootstrap_room values on the decode engine's /generate and from chunk_idx in ZeroMQ staging frames; the second needs reach to the internal rank port. Through 0.5.19 and 0.5.20.
  • CVE-2026-93088 (CERT/CC CNA, 2026-09-22): the multimodal generation runtime's DiffusionServer binds an unauthenticated ZeroMQ ROUTER socket to a network interface and passes the last frame of each message to pickle.loads() before validation; 0.5.11 through 0.5.14. CVE-2026-94570 (CERT/CC CNA, same day): unvalidated AUX_DATA control messages kill the decode control thread; through 0.5.15.
  • CVE-2026-102634 (VulnCheck, 2026-09-29, 8.7): duplicate bootstrap_room values crash scheduler processes or hang other users' requests until transfer timeout; through 0.5.20.

October: pickle persists with the flag off, the dumper is hit again, and fixes wait in open pull requests

  • CVE-2026-93034 (CERT/CC CNA, 2026-10-08): the ZeroMQ message decoder unconditionally deserializes PickleWrapper payloads through pickle.loads() in _maybe_unwrap_pickle with no allowlist and no authentication, "persists via the msgpack path even when SGLANG_USE_PICKLE_IPC is disabled," and becomes remotely exploitable when data-parallel attention is enabled with a non-loopback --dist-init-addr. Through v0.5.20. This record undoes the one mitigation CERT/CC offered in July; the flag does not remove the pickle path.
  • CVE-2026-109225, CVE-2026-109228, CVE-2026-109229 (VulnCheck, 2026-10-12, 8.7 each): memory exhaustion through oversized /v1/audio/transcriptions uploads read fully before validation, a GLM-V video path that lets the request override frame and token budgets, and a NanoNemotronVL image processor that sets Pillow's MAX_IMAGE_PIXELS to None process-wide, re-enabling decompression bombs for every image the server decodes. Through 0.5.21.
  • CVE-2026-110807 and CVE-2026-110809 (VulDB, 2026-10-14, 5.3 each): two session-handling crashes on /generate, 0.5.0 through 0.5.19; the records say fix pull requests #41535 and #41483 "await acceptance" and that the project "has not responded" to the issue. CVE-2026-105245 (VulDB, 2026-10-05, 6.3): /server_info sends the API key in cleartext, through 0.5.21, fix PR #30343 awaiting acceptance.
  • CVE-2026-111391 (VulnCheck, 2026-10-16, CVSS 4.0 9.2, 3.1 8.1; credited to Jiapeng Li, Jiajia Liu, Qiang Fu and Jiadai Wang): _evaluate_filter() in the dumper evaluates a caller-supplied filter expression with eval(), the restriction can be escaped through a regex function's globals, and the unauthenticated /dumper/configure endpoint accepts the expression when DUMPER_SERVER_PORT is set; the code runs in the scheduler process on the next forward pass. Range 0.5.10 through 0.5.22, which is the current release, published 2026-10-16, the same day as the record. The reporter's issue #44188 (opened 2026-10-14) is open with no maintainer comment. Two fix PRs exist: #44205 (an AST-based evaluator) was closed unmerged on 2026-10-14 by a maintainer who also blocked its author, and #44782 (a restricted AST walker with regression tests) is open with CI waiting on a label. Neither is a fix a user can install. This is the second dumper eval() record after July's CVE-2026-15971, which CERT/CC listed through 0.5.15 with no fix; whether the two are the same code path with a widened range or two bugs is not stated by either CNA, and the records carry different reporters.
  • CVE-2026-111392 (VulnCheck, 2026-10-16, 6.3): /generate trusts caller-supplied mm_hashes as the multimodal prefix-cache key, so a different image sent under a known or predicted hash reads another request's cached image content or corrupts its responses, across tenants. 0.5.13 through 0.5.21. Fix PR #44653 is open: it ignores caller hashes by default and honours them only behind a new --trust-caller-mm-hashes flag, which is the right default if it merges; four code owners are requested and none has approved.

2026-10-19: five more VulnCheck records, the same reporters, and the first one against the router

  • CVE-2026-112266 (VulnCheck, 2026-10-19, CVSS 4.0 8.2, 3.1 5.9): a streaming /generate request carrying a one-character rid that then disconnects reaches prefix-matching abort logic in the scheduler, which terminates every other client's in-flight request. Through 0.5.22. The reporter's issues are #45002 and #41474.
  • CVE-2026-112267 (6.9, 3.1 6.5): in prefill/decode disaggregation mode the Decode worker's /generate accepts caller-supplied bootstrap_host and bootstrap_port, so an unauthenticated caller makes the worker open connections to internal hosts and ports and blocks the shared scheduler loop while it does. Through 0.5.22. Issue #45008.
  • CVE-2026-112268 (5.3, 3.1 6.3): sglang-router, the sgl-model-gateway package, through 0.3.2: the /ha/* mesh management routes skip the control-plane Admin role check, so a holder of the data-plane API key reads cluster topology, writes gossiped configuration, changes global rate limits and can call POST /ha/shutdown to dissolve HA coordination. Fix PR #45017 was opened 2026-10-18 and on 10-19 is open with two reviewers requested, no review, and required checks failing (the title-format check and one test run). PyPI sglang-router latest is 0.3.2.
  • CVE-2026-112269 and CVE-2026-112270 (7.1, 3.1 6.5 each): with the Mooncake disaggregation backend, the Prefill rank's ZMQ PULL socket accepts unauthenticated decode registrations and STAGING_RSP messages; many registrations with unique session ids and large nested buffer frames, or STAGING_RSP messages with huge chunk_idx values under fresh room ids, exhaust Prefill memory until the scheduler is OOM-killed. The rank address is readable from /route. Network-adjacent. Through 0.5.22. Issues #45012 and #45014.

The five records credit Mingkai Yu, Jiadai Wang and Jiajia Liu, with Qiang Fu on three, so three of the four names from the 2026-10-16 dumper record continue. PyPI sglang latest is still 0.5.22 (2026-10-16) and no release carries any fix for any record in this file. The count moves from twenty-two to twenty-seven, and the router record is the first filed against the gateway package rather than the server; a gateway deployment that hands tenants a data-plane key is the population for it.

Why one file

Twenty-seven records across three CNAs and at least six reporters is one story: an inference server whose management, debug and inter-process surfaces assume a trusted network, a maintainer channel that CERT/CC, VicOne and VulDB each describe as unresponsive, and a security tab that has never published anything. LMCache and Xoscar under Xinference are the same class in the same fortnight, and the November 2025 ShadowMQ research named the pattern. Severity is high rather than the CNA's critical because every code-execution record needs a non-default setting (the dumper port, no API key, data-parallel attention on a routable address, disaggregation mode); a default single-node sglang.launch_server behind an API key is reached by the denial-of-service records only. Status is active: the newest RCE record covers the current release with no fix, and no record in the wave names a fixed version.

Am I affected?

pip show sglang 2>/dev/null | grep -i '^version'        # ranges per record are in the body: the July six through 0.5.15, the September records through 0.5.14 to 0.5.20, the October records through 0.5.21 or 0.5.22; no record names a fixed version
# The settings that turn a record into remote code execution:
env | grep -E 'DUMPER_SERVER_PORT|SGLANG_USE_PICKLE_IPC'   # dumper set = CVE-2026-111391 and CVE-2026-15971 reachable
pgrep -af launch_server | grep -oE -- '--(api-key|admin-api-key|dist-init-addr|dp-size|enable-dp-attention|disaggregation-mode)[= ]?\S*'
# No --api-key: /update_weights_from_tensor and the weight-broadcast routes answer anyone (CVE-2026-86793, -15978)
# --admin-api-key set without --api-key: /server_info returns the keys and the SSL key path (CVE-2026-15977)
# --enable-dp-attention with a non-loopback --dist-init-addr: CVE-2026-93034 is remote
# --disaggregation-mode prefill|decode: the bootstrap PUT /route and bootstrap_room records apply
ss -ltnp 2>/dev/null | grep -E 'python|sglang'              # anything bound to 0.0.0.0 that is not the API port is an internal socket on a routable address

Affected if any of those settings is on and the port is reachable from a network you do not control. The denial-of-service records apply to any 0.5.x server that accepts multimodal or audio requests from untrusted clients regardless of settings.

If you are affected

There is no upgrade that closes these ids as of 2026-10-19 (sglang 0.5.22 and sglang-router 0.3.2 remain the latest PyPI releases, with no fix for any id in this file). Unset DUMPER_SERVER_PORT outside a debugging session; set --api-key and --admin-api-key and put the server behind an authenticating proxy; keep --dist-init-addr, the ZeroMQ rank ports and the disaggregation bootstrap service on loopback or a private network with no route from clients; prefer safetensors and reject .bin and .pt weight files from sources you do not control; cap request body size at the proxy for the upload and multimodal routes. If /server_info was reachable without a key, rotate the API and admin keys. If the dumper port or an unauthenticated weight-update route was reachable from an untrusted network, treat the host as compromised and follow if-your-webapp-was-compromised.md and rotating-cloud-credentials.md; a rejected request in the logs does not show the attack failed, because the pickle and eval paths run before the handler. Watch the two open pull requests (#44782, #44653) and the release notes; a merge is not a release.

Prevention

  • An inference server's debug, weight-update and inter-process ports are a control plane; isolate them the way supply-chain-attack-surface.md says to isolate any unauthenticated service, and run the process as a non-root user in a container that holds no other credentials (agent-sandboxing.md).
  • Pick inference software by its disclosure channel as well as its throughput: a project whose maintainers do not answer CERT/CC and whose security tab is empty puts the whole patch burden on you (package-vetting-checklist.md).

Sources