MCP has two transports. The remote one speaks over HTTP and gets most of the security attention. The local one, STDIO, is quieter and more dangerous, because of what it actually does: to connect a local MCP server, the host process launches that server as a child process and talks to it over standard input and output. The server is defined in configuration by a command and an args array. There is no network in the middle. The transport is a process launch. That is reasonable when the config is the operator's own. It stops being reasonable the moment someone else can set that field, because the field is then an instruction to run a program of their choosing. Verifiable security starts with naming that plainly: an MCP stdio config is a command line.
How the Flowise bug works
Flowise is a visual builder for LLM agents. One of its nodes is a Custom MCP server, and it lets an authenticated user register a local MCP server by supplying the command and arguments the host should run. The maintainers knew this was dangerous, so they wrote sanitizers to police it: validateCommandInjection to reject shell-metacharacter tricks, and validateArgsForLocalFileAccess to constrain what the arguments can touch. The problem, fixed in flowise-components 3.1.0, is that those filters reason about the wrong threat. They look for classic injection punctuation and for arguments that reach sensitive files. They do not stop a perfectly well-formed launch of a legitimate program that itself runs arbitrary code.
That is the whole trick, and it is why it earns a 9.9 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H). You do not need a semicolon or a backtick to get code execution when the command you are allowed to specify is a launcher. A package runner such as npx exists precisely to fetch and execute code by name. Handed to the subprocess spawner as a clean command with clean-looking arguments, it sails past filters watching for shell syntax and runs whatever it was pointed at with the privileges of the Flowise process. The scope-changed flag in the vector string is the tell: execution escapes the node and becomes control of the host. We will not print a weaponized launcher line here. The point for a defender is the shape, not the payload: a sanitizer that blocks metacharacters but permits arbitrary executables is not a control, it is a speed bump.
The same class shows up with a different surface in codebase-mcp, tracked as CVE-2026-5023. There, a RepoMix command handler concatenates user-supplied parameters straight into a shell string, so the injection is the old-fashioned kind, string building into a shell. It is scored lower, 4.8, because reaching it requires local access and no vendor patch existed at disclosure. Two very different bugs, one lesson: the MCP server-management surface treats a config field or a tool parameter as if it were safe text, when it is actually an instruction to the operating system.
The vulnerable surface is architectural: any path that lets untrusted input reach an MCP stdio command field is a path to a process launch. Illustrative, not from any specific host.
Why this is a class, not a single CVE
Researchers at OX Security and the Cloud Security Alliance documented this in April 2026 as a design-level problem across the AI ecosystem, and that framing is the one to keep. The class does not depend on any one product's bug. It depends on a structural fact: an MCP config field is effectively a shell, so the risk is set by two variables. First, who can write to that field. Second, how weak the sanitizer in front of it is. When the field is reachable by an ordinary authenticated user, as in Flowise, you have post-auth RCE. When the server-management endpoint is exposed with no authentication at all, which is not hypothetical on self-hosted agent platforms, you have pre-authentication RCE, and the sanitizer is the only thing between the internet and a process launch on your host.
A sanitizer that blocks shell metacharacters but permits arbitrary executables is not a control. It is a speed bump in front of a command line.
Be precise about scope, because that precision is the brand. This is not a claim that MCP is unsafe or that every agent host is exploitable. Plenty of deployments never expose the server-management surface, gate it behind strong authentication, or run only vetted, pinned commands. The work is to determine, for your environment, which AI hosts expose an MCP configuration path, who can reach it, and what stands in front of it. Where a public catalog assigns a CVE to a specific build, as with Flowise before 3.1.0, that is a vendor-code vulnerability and patching is the fix. What we add is the exposure determination: which of your agent hosts turn a config field into a shell, and for whom.
How to recognize your exposure
You can assess this without firing a single exploit, because the exposure is three readable facts.
- Inventory the MCP hosts. Flowise, LangFlow, and the agent frameworks your teams have self-hosted. Each one that supports a local MCP or custom-tool node has a command surface to account for.
- Determine who can add or edit an MCP server, and whether the config UI or API is authenticated. The single highest-signal fact is reachability: an unauthenticated server-management endpoint is pre-auth RCE by construction, independent of any CVE.
- Version-check Flowise against the fixed 3.1.0 build. A public-facing instance below that line carries the catalog's risk directly, and version is the cleanest evidence you can read without touching the running system.
Find and close MCP stdio command execution
- List every self-hosted agent builder and note which support a local MCP or custom-command node. That node is the surface; if it exists, it needs a control in front of it.
- Prove whether the server-registration path requires authentication, and from where it answers. An unauthenticated or internet-facing config endpoint is the finding, not a nuance of it.
- Fingerprint Flowise versions and flag anything below 3.1.0. Treat a public-facing, pre-3.1.0 instance as an active risk tied to CVE-2026-40933, not a queued upgrade.
- Replace metacharacter-only filtering with an allow-list of vetted, pinned commands. A deny-list of shell punctuation cannot see a clean launcher; only an allow-list of specific executables closes the class.
- Reduce the privilege of the agent-host process. The blast radius of an MCP launch is the privilege of the host that spawns it; a least-privilege account shrinks the worst case before any bug is found.
How Celvex catches this
Find. Prove. Fix. Verify.
A read-only sweep inventories your self-hosted MCP hosts, identifies which expose a server-registration or custom-command surface, checks whether that surface is authenticated, and fingerprints Flowise against the fixed 3.1.0 build.
On an authorized instance, a benign stdio command writes a marker file to confirm execution. That, plus the version and registration-endpoint auth evidence, becomes an Ed25519-signed Proof Capsule you can reproduce offline.
The capsule names the steps: upgrade Flowise to 3.1.0 or later, gate MCP-server registration behind strong auth and an allow-list of vetted commands, and never expose the config API unauthenticated.
A fresh sweep confirms the marker command is now rejected or sandboxed and the registration endpoint requires auth. The finding closes and the verified-fix event is recorded for the audit trail.
The reason this class will keep producing findings is that AI tooling is filed under developer convenience, so the input-validation scrutiny an application security team would demand of any other web-facing config is quietly skipped for the agent builder. The discipline is the same boundary question we ask everywhere: which of my systems let untrusted input reach an interpreter, and here the interpreter is the operating system itself. Answer it for every MCP host, and a config field stops being a shell you did not know you had exposed.
Verifiable security. Find it. Prove it. Fix it. Verify the fix held. That is what we ship.
Sources
- NVD: CVE-2026-40933 (Flowise custom MCP stdio command injection)
- OX Security: MCP supply-chain advisory, RCE vulnerabilities across the AI ecosystem
- SentinelOne: CVE-2026-5023 (codebase-mcp RepoMix command injection)
- MITRE CWE-78: OS Command Injection
- MITRE CWE-77: Command Injection
- CELVEX Group: Proof Capsule format
Which of your AI hosts turn a config field into a shell?
Free Exposure Check, no signup required. We inventory your self-hosted MCP and agent builders, test whether the server-registration surface is authenticated, fingerprint Flowise against the fixed build, and ship a signed Proof Capsule for the highest-confidence finding.
Run a Free Scan →