# CVE-2026-45018: Chainlit MCP stdio unauthenticated RCE (and sibling CVE-2026-45019)

> Source: <https://dev.to/hol/cve-2026-45018-chainlit-mcp-stdio-unauthenticated-rce-and-sibling-cve-2026-45019-30bp>
> Published: 2026-08-31 04:45:39+00:00

*Originally published at HOL*

Chainlit 2.12.0 (2026-08-25) closes two bugs on `/mcp`

. CVE-2026-45018 is unauthenticated command execution via the MCP stdio transport. CVE-2026-45019 is unauthenticated SSRF via SSE and streamable-http. Both require `features.mcp.enabled = true`

. MCP is off by default since 2.7.0. If that flag is false, you can stop here.

`features.mcp.enabled`

is missing or false in `.chainlit/config.toml`

.This is not every MCP CVE in the ecosystem. It is not LiteLLM's authenticated MCP stdio test-endpoint issue.

With MCP on, `POST /mcp`

accepted a client-supplied `fullCommand`

when `clientType`

was `stdio`

. `validate_mcp_command()`

in `backend/chainlit/mcp.py`

split the string and checked only the executable basename against `allowed_executables`

(examples: `npx`

, `uvx`

). Arguments were not inspected. Common Node launchers can run an arbitrary shell string through a short flag, so an allowlisted basename plus client-controlled arguments still ran as the Chainlit user before the MCP handshake failed. SPL Security (Vipin and Stephen) reported working proofs against 2.11.0. Vendor severity for SPL-2026-001 / CVE-2026-45018 is CVSS 3.1 9.8. Affected range: `>=2.4.0rc0, <2.12.0`

with MCP enabled. GitHub advisory GHSA-w3fx-mc44-mf6j.

CVE-2026-45019 (SPL-2026-002, CVSS 3.1 7.2, GHSA-hvfh-5mj3-5f3j) is the sibling. For `sse`

and `streamable-http`

, the same endpoint took a raw `url`

and optional `headers`

with no scheme check, no host allowlist, and no header denylist. The process made outbound HTTP, including caller-controlled auth headers, toward internal hosts and link-local metadata endpoints. Blind SSRF: response bodies stay inside the MCP client. Header forwarding for that path arrived in 2.6.4.

If `allowed_executables`

is removed so the value is `None`

, validation allows every executable. The allowlist is not a safety net by itself.

Not default-on. Not fixed by shrinking `allowed_executables`

; 2.12.0 removes client-supplied commands. After upgrade, anonymous clients can still start developer-named stdio servers by name if auth is off. That is pinned-command start, not client-chosen RCE.

Run `pip show chainlit`

and print `chainlit.__version__`

from the same environment that serves the app. Open `.chainlit/config.toml`

and look for `features.mcp.enabled`

, `allowed_executables`

, `user_servers`

, and `[[features.mcp.servers]]`

. A Version below 2.12.0 with MCP enabled is exposed. Restart after upgrade so an old wheel is not still listening.

```
pip install --upgrade 'chainlit==2.12.0'
```

Then restart Chainlit. 2.12.0 breaks old MCP config: `[features.mcp.sse]`

, `[features.mcp.stdio]`

, `[features.mcp.streamable-http]`

, and `allowed_executables`

abort startup when MCP is on. Declare stdio servers under `[[features.mcp.servers]]`

and connect by name. User-provided SSE/HTTP needs `[features.mcp.user_servers] enabled = true`

and a non-empty `allowed_urls`

. Redirects are not followed; put the final HTTPS URL in config.

If you cannot upgrade today: set `features.mcp.enabled = false`

, restrict egress, and register auth so `/mcp`

is not anonymous. Auth alone does not remove command execution for an authenticated user on vulnerable builds; it only removes the anonymous path.

GitHub advisory pages still showed empty patched versions at research time; the 2.12.0 release and in-tree MCP advisory name 2.12.0 as the fix.

This is the operator write-up. The [HOL Guard evidence page](https://hol.org/guard/security/cves/CVE-2026-45018?utm_source=devto&utm_medium=syndication&utm_campaign=blog_distribution&utm_content=cve-2026-45018-chainlit-mcp-stdio-unauth-rce-2) is the source record for CVE-2026-45018; sibling evidence for CVE-2026-45019 is at [HOL Guard CVE-2026-45019](https://hol.org/guard/security/cves/CVE-2026-45019?utm_source=devto&utm_medium=syndication&utm_campaign=blog_distribution&utm_content=cve-2026-45018-chainlit-mcp-stdio-unauth-rce-2).
