// threat brief

SGLang debug dumper eval injection: a filter expression can escape the sandbox and run arbitrary Python in the scheduler process

CVSS
9.2 CRITICAL
CISA KEV
Not listed
Weakness
CWE-95

PlainCVE Team · Published 2026-10-20 · AI-assisted · Press brief ↓

AI review 2026-10-20 (not human-reviewed)Command tests: none yetReproduced: not yetVerification record ↓

SGLang's debug dumper runs filter expressions through Python eval(); a sandbox escape lets attackers run code. No fixed version confirmed.

Who is affectedDeployments running SGLang 0.5.10 through 0.5.22 with DUMPER_SERVER_PORT set. The prerequisites depend on the mode. With a numeric port, the v0.5.22 code starts a separate dumper server bound to 0.0.0.0 (all network interfaces) with no authentication check, so anyone who can reach that port can exploit it (the researcher's write-up says the same, and the CVE record also calls the endpoint unauthenticated). With reuse, the dumper routes are added to the main API; per the reporter, the attacker needs to reach /dumper/configure and /generate, and either no admin_api_key is configured or the attacker holds the admin key.
What happensAn attacker can run arbitrary Python code inside SGLang's scheduler process. The reporter says this code can read model files, mounted credentials, environment variables and process memory.
What to do nowNo source names a fixed version yet. Until an official fix exists, a third party advises leaving DUMPER_SERVER_PORT unset and restricting who can reach /dumper/configure.
Affected versions0.5.10 through 0.5.22 (inclusive)
Fixed versionsUnconfirmed; no source names a fixed version
CVSS vector
Show full vectorCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Timeline
  • First public 2026-10-14

Blue team playbook

Check, fix / mitigate, respond, harden. Matching the affected versions does not mean you were compromised, and a check that finds nothing does not prove you are safe; each item says what it can and cannot show. Tagged steps point to where the attack flow below can be stopped.

DETECTCheckAm I affected? Any signs of compromise?
  1. 01Check your SGLang version

    0.5.10 through 0.5.22 are in the affected range (CVE record and VulnCheck advisory). Run this on the host, container or Python virtual environment (venv) that runs SGLang; in another Python environment it will find nothing or the wrong version. For containers, use docker exec <container-name> pip show sglang (read-only).

    Read-only check
    pip show sglang | grep -i '^version'
  2. 02Check whether DUMPER_SERVER_PORT is set

    If this environment variable is not set, there is no dumper endpoint to exploit; a number means a separate, unauthenticated dumper port open on all network interfaces, and reuse means the routes sit on the main API. Run it on the host or inside the container where the SGLang service runs, because your current shell's environment may differ from the service process's. For containers, use docker exec <container-name> env | grep -i DUMPER_SERVER_PORT (read-only), and also check your docker compose file or systemd unit.

    Read-only check
    env | grep -i DUMPER_SERVER_PORT
  3. 03Look for calls to /dumper/configure

    Run this on the reverse proxy or the SGLang host; it searches the log folder recursively (adjust the path to your deployment). Rotated, compressed logs (.gz) need zgrep. In numeric-port mode the dumper server listens on its own port and may not pass through the reverse proxy, so proxy logs may miss these calls; PlainCVE suggests also checking the SGLang service's own output logs and firewall logs. If you don't use the dumper yourself, any outside call deserves investigation.

    Read-only check
    grep -rn '/dumper/configure' /var/log/nginx/
MITIGATEFix / mitigatePatch; block it if you cannot patch yet
  1. 01Leave DUMPER_SERVER_PORT unset

    Third-party threat feed advice (OffSeq): until a fix is available, avoid setting this variable if possible. No fixed version is confirmed yet.

  2. 02Restrict access to /dumper/configure

    Also OffSeq's advice: if you must use the dumper, restrict this endpoint to trusted sources at your reverse proxy or firewall.

  3. 03Set an admin_api_key

    Applies only to DUMPER_SERVER_PORT=reuse. PlainCVE's inference from the reporter's prerequisites: in reuse mode without an admin_api_key, any ordinary API key holder can exploit this; setting one narrows who can exploit it, but the eval flaw remains. With a numeric DUMPER_SERVER_PORT, the dumper server performs no authentication check (v0.5.22 code), so admin_api_key has no effect.

RESPONDRespondIf you find signs of compromise
  1. 01If you find suspicious calls, treat the host as compromised

    PlainCVE suggestion: rotate the credentials and keys in environment variables the scheduler could read, and check the host for unusual processes or files. This is a precaution, not a confirmation of a leak.

  2. 02Track the official fix

    Follow GitHub issue #44188 (that page contains exploit code; we do not link it) and the official SGLang release notes. Community PR #44205 was closed by a maintainer without being merged (the maintainer closed many PRs from the same account at once); do not treat it as a fix. No source confirms the maintainers have released a fix or published an advisory.

HARDENHardenPrevent the next one
  1. 01Don't expose SGLang or the dumper port directly

    A researcher notes that in the versions they reviewed, the main SGLang server binds to loopback by default. But the same write-up and the v0.5.22 code show that with a numeric DUMPER_SERVER_PORT, the dumper server binds separately to 0.0.0.0 (all network interfaces) with no authentication, so a loopback-only main server does not protect it. PlainCVE suggestion: keep the main server off outside interfaces and block the dumper port at the firewall.

  2. 02Keep debug features off in production

    PlainCVE suggestion: enable debug features such as the dumper only in isolated test environments.

  3. 03Give inference hosts least-privilege credentials

    Even if code runs, there is less for it to read.

Full remediation steps and notes
  1. No fixed version is confirmed. No source names one. The GitHub Advisory entry is unreviewed and links no advisory from the SGLang project itself; our analysis is that the project probably had not published one when it was captured. A third-party threat feed also says patch status is not confirmed.
  2. Close the entry point first. The playbook items “leave DUMPER_SERVER_PORT unset” and “restrict access to /dumper/configure” are OffSeq’s advice, not the vendor’s. Setting an admin_api_key only reduces who can exploit this in reuse mode; it does not replace those two steps. In numeric-port mode the dumper server performs no authentication check, so admin_api_key has no effect.
  3. Order of checks. Check the version first, then DUMPER_SERVER_PORT; only if both apply do you need to dig through access logs. When checking the variable, look at how the service is actually launched (container, systemd and so on), not just your own terminal.
  4. Once a fix ships. Before upgrading, confirm the release notes actually mention a fix to _evaluate_filter or the dumper. Until then, don’t assume a version after 0.5.22 is safe.

Attack flow

Read left to right: this is the order the attack happens in. A blue shield means the step can be stopped; the earlier, the better. Click an icon for details.

Read top to bottom: this is the order the attack happens in. A blue shield means the step can be stopped; the earlier, the better. Tap an icon for details.

SGLang debug dumper eval injection: a filter expression can escape the sandbox and run arbitrary Python in the scheduler process: 1. The attacker reaches the /dumper/configure endpoint → 2. The endpoint does not block the request → 3. Sends a crafted filter expression → 4. The injected code runs on the next model execution → 5. Reads model files, credentials and environment variablesCVE-2026-111391 · SGLang debug dumper eval injection: a filter expression can escape the sandbox and runarbitrary Python in the scheduler processAttackerYour systemThe attacker reaches the /dumper/configure endpoint — This debug endpoint exists only when DUMPER_SERVER_PORT is set. With a numeric port, the dumper opens its own HTTP server bound to 0.0.0.0 (all network interfaces) (v0.5.22 code). The reporter instead describes DUMPER_SERVER_PORT=reuse, which adds the dumper routes to the main model API; per the reporter's prerequisites, the attacker also needs access to the /generate endpoint. 1The attackerreaches the/dumper/configureendpointThe endpoint does not block the request — In numeric-port mode, the dumper server in the v0.5.22 code performs no authentication check (the CVE record also calls the endpoint unauthenticated). In reuse mode, according to the reporter: with no API key configured, no login is needed; with an ordinary API key but no admin_api_key, anyone holding the ordinary key can use it. 2The endpoint doesnot block therequestSends a crafted filter expression — _evaluate_filter() runs this filter with Python's eval(). It runs in a restricted environment, but the re.search function available there leads back to its module's global variables, letting the attacker escape the restriction. 3Sends a craftedfilter expressionThe injected code runs on the next model execution — The code doesn't run immediately; it runs in the scheduler process when the next model execution (forward pass) reaches a dumper hook. 4The injected coderuns on the nextmodel executionReads model files, credentials and environment variables — The reporter's assessment: arbitrary code can read the model files, mounted credentials, environment variables and process memory available to the scheduler. 5Reads model files,credentials andenvironmentvariablesAttack pathCan be stopped herePlainCVE · plaincve.date/en/vulns/cve-2026-111391-sglang-dumper-eval-injection · CC BY 4.0
SGLang debug dumper eval injection: a filter expression can escape the sandbox and run arbitrary Python in the scheduler process: 1. The attacker reaches the /dumper/configure endpoint → 2. The endpoint does not block the request → 3. Sends a crafted filter expression → 4. The injected code runs on the next model execution → 5. Reads model files, credentials and environment variablesCVE-2026-111391 · SGLang debug dumpereval injection: a filter expression canescape the sandbox and run arbitraryPython in the scheduler processThe attacker reaches the /dumper/configure endpoint — This debug endpoint exists only when DUMPER_SERVER_PORT is set. With a numeric port, the dumper opens its own HTTP server bound to 0.0.0.0 (all network interfaces) (v0.5.22 code). The reporter instead describes DUMPER_SERVER_PORT=reuse, which adds the dumper routes to the main model API; per the reporter's prerequisites, the attacker also needs access to the /generate endpoint. 1AttackerThe attacker reaches the/dumper/configure endpointThe endpoint does not block the request — In numeric-port mode, the dumper server in the v0.5.22 code performs no authentication check (the CVE record also calls the endpoint unauthenticated). In reuse mode, according to the reporter: with no API key configured, no login is needed; with an ordinary API key but no admin_api_key, anyone holding the ordinary key can use it. 2Your systemThe endpoint does not block therequestSends a crafted filter expression — _evaluate_filter() runs this filter with Python's eval(). It runs in a restricted environment, but the re.search function available there leads back to its module's global variables, letting the attacker escape the restriction. 3AttackerSends a crafted filterexpressionThe injected code runs on the next model execution — The code doesn't run immediately; it runs in the scheduler process when the next model execution (forward pass) reaches a dumper hook. 4Your systemThe injected code runs on thenext model executionReads model files, credentials and environment variables — The reporter's assessment: arbitrary code can read the model files, mounted credentials, environment variables and process memory available to the scheduler. 5AttackerReads model files, credentialsand environment variablesAttack pathCan be stopped herePlainCVE · CC BY 4.0plaincve.date/en/vulns/cve-2026-111391-sglang-dumper-eval-injection
Free to use in reporting and teaching under CC BY 4.0. Attribution is already on the image.
  1. Attacker

    The attacker reaches the /dumper/configure endpoint

    This debug endpoint exists only when DUMPER_SERVER_PORT is set. With a numeric port, the dumper opens its own HTTP server bound to 0.0.0.0 (all network interfaces) (v0.5.22 code). The reporter instead describes DUMPER_SERVER_PORT=reuse, which adds the dumper routes to the main model API; per the reporter's prerequisites, the attacker also needs access to the /generate endpoint.

    Defense: Leave DUMPER_SERVER_PORT unset, restrict access to /dumper/configure and the dumper port, and don't expose SGLang to untrusted networks.

  2. Your system

    The endpoint does not block the request

    In numeric-port mode, the dumper server in the v0.5.22 code performs no authentication check (the CVE record also calls the endpoint unauthenticated). In reuse mode, according to the reporter: with no API key configured, no login is needed; with an ordinary API key but no admin_api_key, anyone holding the ordinary key can use it.

    Defense: PlainCVE suggestion: if you must enable the dumper, use reuse mode only and set an admin_api_key; in numeric-port mode admin_api_key has no effect. This narrows who can exploit it; it does not fix the eval problem.

  3. Attacker

    Sends a crafted filter expression

    _evaluate_filter() runs this filter with Python's eval(). It runs in a restricted environment, but the re.search function available there leads back to its module's global variables, letting the attacker escape the restriction.

    Defense: The real fix, replacing eval with a parser that doesn't run code, has to come from an official patch; until then users can only turn the dumper off.

  4. Your system

    The injected code runs on the next model execution

    The code doesn't run immediately; it runs in the scheduler process when the next model execution (forward pass) reaches a dumper hook.

  5. Attacker

    Reads model files, credentials and environment variables

    The reporter's assessment: arbitrary code can read the model files, mounted credentials, environment variables and process memory available to the scheduler.

    Defense: Give the SGLang host only least-privilege credentials to limit what can leak.

Who is affected

ConditionAffected?
SGLang 0.5.10 through 0.5.22 + DUMPER_SERVER_PORT set to a numeric port + attacker can reach that dumper portAffected, no authentication needed (v0.5.22 code: the dumper server binds to 0.0.0.0 with no authentication check; the researcher’s write-up and the CVE record also say unauthenticated)
SGLang 0.5.10 through 0.5.22 + DUMPER_SERVER_PORT=reuse + /dumper/configure and /generate reachable by the attacker, with no API key configuredAffected, no login needed (per the reporter)
As above (reuse mode), with an ordinary API key but no admin_api_keyAffected, any ordinary key holder can exploit it (per the reporter)
As above (reuse mode), with an admin_api_keyOnly holders of the admin key can exploit it (per the reporter)
DUMPER_SERVER_PORT not setNo dumper endpoint to exploit
Before 0.5.10 or after 0.5.22Not listed in the CVE record; no source names a fixed version

The reporter reproduced the issue on 0.5.19.

sglang 0.5.22 was uploaded to PyPI on 2026-10-16 and has not been yanked, so it is a published release (PyPI release metadata).

Authentication depends on the mode: the CVE record (published by VulnCheck, not the SGLang project) calls /dumper/configure unauthenticated; the reporter says it needs no login only when no API key is configured. Tracing this to the v0.5.22 code, the two accounts describe different modes rather than contradicting each other. With a numeric DUMPER_SERVER_PORT, the dumper starts a separate HTTP server bound to 0.0.0.0 (all network interfaces) that performs no authentication check. With reuse, the dumper routes sit on the main API and, per the reporter and the researcher, follow the main server’s admin policy (without an admin_api_key, anyone holding an ordinary key can exploit it).

Separately, a researcher notes that in the versions they reviewed, the main SGLang server binds to loopback by default, meaning only the same machine can connect. That only protects reuse mode: the same write-up and the v0.5.22 code show the numeric-port dumper server binds to all network interfaces, which a loopback-only main server does not prevent.

How it works

SGLang is an open-source framework, hosted by LMSYS, for serving large language models. It has an optional “debug dumper” that records internal data while the model runs. Through the /dumper/configure endpoint, a user can set a “filter expression” that decides what gets recorded.

The problem is in a function called _evaluate_filter(): it checks the filter using Python’s eval(), a built-in that runs a piece of text as code. The developers ran it in a restricted environment that offers only a few helpers, such as re.search. But a Python function object carries a link to its module’s global variables, and an attacker can follow that link to reach things they shouldn’t, escaping the restriction. This kind of weakness is called eval injection (CWE-95).

The injected code doesn’t run right away. It runs inside SGLang’s scheduler process the next time a model execution (forward pass) reaches a dumper hook. The reporter says this code can read the model files, mounted credentials, environment variables and process memory available to the scheduler.

The flawed approach (conceptual illustration, not the original source code):

Show code example(python)
# The restricted environment still contains function objects, which can lead back to much more
def evaluate_filter(expr, record):
    return eval(expr, {"__builtins__": {}, "re": some_regex_helpers}, record)

A safer approach:

Show code example(python)
import ast
ALLOWED = (ast.Expression, ast.Compare, ast.BoolOp, ast.Name, ast.Constant, ...)

def evaluate_filter(expr, record):
    tree = ast.parse(expr, mode="eval")
    for node in ast.walk(tree):
        if not isinstance(node, ALLOWED):
            raise ValueError("syntax not allowed")
        # Always reject double-underscore attributes, and expose no function objects
    return safe_interpret(tree, record)  # interpret it yourself; never call eval

This matches the reporter’s advice: don’t evaluate the filter with eval; use a structured parser or a restricted evaluator that exposes no function objects. A commenter who is not a maintainer opened PR #44205 to replace eval with a whitelist-based AST evaluator. A maintainer closed that PR without merging it (closing it together with the other PRs the same account opened, 37 in a short period, citing insufficient validation and testing), so it does not count as a fix.

Timeline

DateEvent
2026-07-30CERT/CC publishes CVE-2026-15971 (dumper sandbox escape when DUMPER_SERVER_PORT is set, listing versions up to v0.5.15; it does not mention _evaluate_filter or re.search, and its relation to this CVE is unconfirmed; the project advisory it cites, GHSA-h6rf-77vv-9mvj, could not be read)
2026-10-14Reporter opens public GitHub issue #44188 (that page contains exploit code; we do not link it); the CVE record also gives this as the public date
2026-10-14A maintainer closes community PR #44205 without merging it (that page contains exploit code; we do not link it)
2026-10-16VulnCheck publishes CVE-2026-111391; sglang 0.5.22 is uploaded to PyPI the same day
2026-10-18As of this date, not in CISA’s Known Exploited Vulnerabilities (KEV) catalog

Further reading

  • Scoring differences: the CVE record lists a CVSS 4.0 score of 9.2 (Critical) and a CVSS 3.1 score of 8.1 (High). They just use different scoring versions. NVD has marked the CVE “Deferred,” meaning it has done no analysis of its own, so this page uses the CVE record’s score.
  • Exploitation: CISA’s SSVC assessment rates exploitation as “poc,” meaning a public proof of concept exists; public GitHub issue #44188 also includes a reproduction (that page contains exploit code; we do not link it). The EPSS score (an estimate of the chance of exploitation in the next 30 days) recorded by the GitHub Advisory Database is about 0.45%. No source reports exploitation in the wild, and none reports zero-day exploitation.
  • Related CVE: the earlier CVE-2026-15971 (assigned by CERT/CC) describes a dumper sandbox escape when DUMPER_SERVER_PORT is set, listing versions up to v0.5.15 (published 2026-07-30); that record does not mention _evaluate_filter or re.search. Our analysis is that the new CVE may describe the same flaw in later versions, or an incomplete fix of it, but no source confirms how the two relate.
  • Credits: the CVE record credits Jiapeng Li, Jiajia Liu, Qiang Fu and Jiadai Wang.
  • Related weakness type: CWE-95 (eval injection).

Verification Checked item by item against sources by AI under our review rules, all passed; not human-reviewed and not yet reproduced in our lab

AI review2026-10-20 · review rules

Verification records describe the environment and the result only, never reproduction steps or code that could attack other people’s systems. See our policy.

Sources

  1. CVE / NVD / OSVCVE-2026-111391 Record · CVE Program (CNA: VulnCheck), 2026-10-16 · accessed 2026-10-18
  2. CVE / NVD / OSVNVD - CVE-2026-111391 · NIST · accessed 2026-10-18
  3. AdvisorySGLang 0.5.10 through 0.5.22 Code Injection via Debug Dumper Filter · VulnCheck · accessed 2026-10-18
  4. OtherGitHub Advisory Database entry for CVE-2026-111391 · GitHub · accessed 2026-10-18
  5. VendorSGLang v0.5.22 dumper.py source code · sgl-project (LMSYS) · accessed 2026-10-18
  6. OtherPyPI sglang 0.5.22 release metadata · PyPI · accessed 2026-10-18
  7. VendorSGLang repository · sgl-project (LMSYS) · accessed 2026-10-18
  8. VendorSGLang releases · sgl-project (LMSYS) · accessed 2026-10-18
  9. NewsCVE-2026-111391 threat entry · OffSeq Radar · accessed 2026-10-18
  10. ResearchSGLang disclosures · Apoorv Dayal · accessed 2026-10-18
  11. CVE / NVD / OSVCVE-2026-15971 Record · CVE Program (CNA: CERT/CC) · accessed 2026-10-18

Press brief

In one sentence

SGLang is an open-source framework, hosted by LMSYS, for serving large language models. Its debug dumper runs user-supplied filter expressions with Python's eval(), and that restriction can be bypassed so an attacker can run arbitrary code on the server. The flaw affects versions 0.5.10 through 0.5.22 and only applies when DUMPER_SERVER_PORT is enabled; no fixed version has been confirmed, and as of 2026-10-18 it is not in CISA's Known Exploited Vulnerabilities catalog.

Key facts

Severity
CVSS 4.0 9.2; CVSS 3.1 8.1 (CVE record) cveawg.mitre.org
Affected versions
sglang 0.5.10 through 0.5.22 vulncheck.com
Publicly reported
2026-10-14 (public date in the CVE record; GitHub issue #44188, which contains exploit code and is not linked here) cveawg.mitre.org
CVE published
2026-10-16 cveawg.mitre.org
NVD status
Deferred (no NVD analysis yet) services.nvd.nist.gov
EPSS
About 0.45% api.github.com

Confirmed

  • _evaluate_filter() runs filters with eval(), and its restricted environment can be escaped via re.search's globals, affecting 0.5.10 through 0.5.22.
  • It applies only when DUMPER_SERVER_PORT is set, and the code runs in the scheduler process on the next model execution.
  • A public proof of concept exists (CISA SSVC rates it 'poc'), but as of 2026-10-18 it is not in CISA KEV.

Unconfirmed / disputed

  • No source names a fixed version; community PR #44205 was closed by a maintainer without being merged.
  • Authentication in reuse mode rests only on the reporter's account (it depends on the API key settings); that numeric-port mode needs no authentication is supported by the v0.5.22 code and the CVE record.
  • No source confirms whether this is the same flaw as the earlier CVE-2026-15971, an incomplete fix of it, or something different.
  • No source reports exploitation in the wild or as a zero-day.

Quotable line

Handing user input to eval() is giving someone the keys and hoping they only open the doors you allowed.

Images

Download the share image (PNG) · Attack flow diagram (downloadable)

Please credit "PlainCVE" and link to this page. Full citation format is under "How to cite" below. Found a factual error? Report it.

How to cite this page

This article is CC BY 4.0. Please keep the attribution and link when republishing.

PlainCVE Team (2026). "SGLang debug dumper eval injection: a filter expression can escape the sandbox and run arbitrary Python in the scheduler process". PlainCVE. https://plaincve.date/en/vulns/cve-2026-111391-sglang-dumper-eval-injection (accessed YYYY-MM-DD)
BibTeX
@misc{cve2026111391sglangdumperevalinjection2026,
  title  = {SGLang debug dumper eval injection: a filter expression can escape the sandbox and run arbitrary Python in the scheduler process},
  author = {PlainCVE Team},
  year   = {2026},
  howpublished = {PlainCVE},
  url    = {https://plaincve.date/en/vulns/cve-2026-111391-sglang-dumper-eval-injection},
  note   = {Updated 2026-10-20}
}